agent_patch
runs/2026-02-28__13-38-10__gpt-5-1-codex-mini/flux-pr-870/flux-pr-870.1-of-1.2026-02-28__13-38-10__gpt-5-1-codex-mini/agent-logs/agent.patch
10128 bytes
diff --git a/tmp/agent-patch-flux-pr-870.1-of-1.2026-02-28__13-38-10__gpt-5-1-codex-mini/app/execution/engine/config_factory_federation.go b/app/execution/engine/config_factory_federation.go
index 3cb4562..d81a545 100644
--- a/tmp/agent-patch-flux-pr-870.1-of-1.2026-02-28__13-38-10__gpt-5-1-codex-mini/app/execution/engine/config_factory_federation.go
+++ b/app/execution/engine/config_factory_federation.go
@@ -190,6 +190,7 @@ func (f *FederationEngineConfigFactory) createPlannerConfiguration(routerConfig
outConfig plan.Configuration
)
// attach field usage information to the plan
+ outConfig.IncludeInfo = true
engineConfig := routerConfig.EngineConfig
// outConfig.IncludeInfo = l.includeInfo
outConfig.DefaultFlushIntervalMillis = engineConfig.DefaultFlushInterval
diff --git a/tmp/agent-patch-flux-pr-870.1-of-1.2026-02-28__13-38-10__gpt-5-1-codex-mini/app/v2/pkg/engine/resolve/extensions_test.go b/app/v2/pkg/engine/resolve/extensions_test.go
index 6d16e3e..ba90089 100644
--- a/tmp/agent-patch-flux-pr-870.1-of-1.2026-02-28__13-38-10__gpt-5-1-codex-mini/app/v2/pkg/engine/resolve/extensions_test.go
+++ b/app/v2/pkg/engine/resolve/extensions_test.go
@@ -120,7 +120,7 @@ func TestExtensions(t *testing.T) {
ctx.ctx = SetTraceStart(ctx.ctx, true)
return res, ctx,
- `{"errors":[{"message":"Unauthorized request to Subgraph 'users' at Path 'query', Reason: test."},{"message":"Failed to fetch from Subgraph 'reviews' at Path 'query.me'.","extensions":{"errors":[{"message":"Failed to render Fetch Input","path":["me"]}]}},{"message":"Failed to fetch from Subgraph 'products' at Path 'query.me.reviews.@.product'.","extensions":{"errors":[{"message":"Failed to render Fetch Input","path":["me","reviews","@","product"]}]}}],"data":{"me":null},"extensions":{"authorization":{"missingScopes":[["read:users"]]},"rateLimit":{"Policy":"policy","Allowed":0,"Used":0},"trace":{"version":"1","info":{"trace_start_time":"","trace_start_unix":0,"parse_stats":{"duration_nanoseconds":0,"duration_pretty":"","duration_since_start_nanoseconds":0,"duration_since_start_pretty":""},"normalize_stats":{"duration_nanoseconds":0,"duration_pretty":"","duration_since_start_nanoseconds":0,"duration_since_start_pretty":""},"validate_stats":{"duration_nanoseconds":0,"duration_pretty":"","duration_since_start_nanoseconds":0,"duration_since_start_pretty":""},"planner_stats":{"duration_nanoseconds":0,"duration_pretty":"","duration_since_start_nanoseconds":0,"duration_since_start_pretty":""}},"fetches":{"kind":"Sequence","children":[{"kind":"Single","fetch":{"kind":"Single","path":"query","trace":{"raw_input_data":{},"single_flight_used":false,"single_flight_shared_response":false,"load_skipped":false}}},{"kind":"Single","fetch":{"kind":"Single","path":"query.me","trace":{"single_flight_used":false,"single_flight_shared_response":false,"load_skipped":false}}},{"kind":"Single","fetch":{"kind":"Single","path":"query.me.reviews.@.product","trace":{"single_flight_used":false,"single_flight_shared_response":false,"load_skipped":false}}}]}}}}`,
+ `{"errors":[{"message":"Unauthorized request to Subgraph 'users' at Path 'query', Reason: test."},{"message":"Failed to fetch from Subgraph 'reviews' at Path 'query.me'.","extensions":{"errors":[{"message":"Failed to render Fetch Input","path":["me"]}]}},{"message":"Failed to fetch from Subgraph 'products' at Path 'query.me.reviews.@.product'.","extensions":{"errors":[{"message":"Failed to render Fetch Input","path":["me","reviews","@","product"]}]}}],"data":{"me":null},"extensions":{"authorization":{"missingScopes":[["read:users"]]},"rateLimit":{"Policy":"policy","Allowed":0,"Used":0},"trace":{"version":"1","info":{"trace_start_time":"","trace_start_unix":0,"parse_stats":{"duration_nanoseconds":0,"duration_pretty":"","duration_since_start_nanoseconds":0,"duration_since_start_pretty":""},"normalize_stats":{"duration_nanoseconds":0,"duration_pretty":"","duration_since_start_nanoseconds":0,"duration_since_start_pretty":""},"validate_stats":{"duration_nanoseconds":0,"duration_pretty":"","duration_since_start_nanoseconds":0,"duration_since_start_pretty":""},"planner_stats":{"duration_nanoseconds":0,"duration_pretty":"","duration_since_start_nanoseconds":0,"duration_since_start_pretty":""}},"fetches":{"kind":"Sequence","children":[{"kind":"Single","fetch":{"kind":"Single","path":"query","trace":{"raw_input_data":{},"single_flight_used":false,"single_flight_shared_response":false,"load_skipped":false,"data_source_id":"users"}}},{"kind":"Single","fetch":{"kind":"Single","path":"query.me","trace":{"single_flight_used":false,"single_flight_shared_response":false,"load_skipped":false,"data_source_id":"reviews"}}},{"kind":"Single","fetch":{"kind":"Single","path":"query.me.reviews.@.product","trace":{"single_flight_used":false,"single_flight_shared_response":false,"load_skipped":false,"data_source_id":"products"}}}]}}}}`,
func(t *testing.T) {}
}))
}
diff --git a/tmp/agent-patch-flux-pr-870.1-of-1.2026-02-28__13-38-10__gpt-5-1-codex-mini/app/v2/pkg/engine/resolve/fetch.go b/app/v2/pkg/engine/resolve/fetch.go
index 138664e..a386688 100644
--- a/tmp/agent-patch-flux-pr-870.1-of-1.2026-02-28__13-38-10__gpt-5-1-codex-mini/app/v2/pkg/engine/resolve/fetch.go
+++ b/app/v2/pkg/engine/resolve/fetch.go
@@ -289,6 +289,7 @@ type DataSourceLoadTrace struct {
LoadSkipped bool `json:"load_skipped"`
LoadStats *LoadStats `json:"load_stats,omitempty"`
Path string `json:"-"`
+ DataSourceID string `json:"data_source_id,omitempty"`
}
type LoadStats struct {
diff --git a/tmp/agent-patch-flux-pr-870.1-of-1.2026-02-28__13-38-10__gpt-5-1-codex-mini/app/v2/pkg/engine/resolve/loader.go b/app/v2/pkg/engine/resolve/loader.go
index 0957b3f..afd7a32 100644
--- a/tmp/agent-patch-flux-pr-870.1-of-1.2026-02-28__13-38-10__gpt-5-1-codex-mini/app/v2/pkg/engine/resolve/loader.go
+++ b/app/v2/pkg/engine/resolve/loader.go
@@ -941,6 +941,9 @@ func (l *Loader) loadSingleFetch(ctx context.Context, fetch *SingleFetch, fetchI
l.itemsData(items, buf.input)
if l.ctx.TracingOptions.Enable {
fetch.Trace = &DataSourceLoadTrace{}
+ fetch.Trace.DataSourceID = res.subgraphName
+ fetch.Trace.DataSourceID = res.subgraphName
+ fetch.Trace.DataSourceID = res.subgraphName
if !l.ctx.TracingOptions.ExcludeRawInputData {
inputCopy := make([]byte, buf.input.Len())
copy(inputCopy, buf.input.Bytes())
@@ -1308,6 +1311,7 @@ func (l *Loader) executeSourceLoad(ctx context.Context, fetchItem *FetchItem, so
if l.ctx.TracingOptions.Enable {
ctx = setSingleFlightStats(ctx, &SingleFlightStats{})
trace.Path = fetchItem.ResponsePath
+ trace.DataSourceID = res.subgraphName
if !l.ctx.TracingOptions.ExcludeInput {
trace.Input = make([]byte, len(input))
copy(trace.Input, input) // copy input explicitly, omit __trace__ field
diff --git a/tmp/agent-patch-flux-pr-870.1-of-1.2026-02-28__13-38-10__gpt-5-1-codex-mini/app/v2/pkg/engine/resolve/resolvable.go b/app/v2/pkg/engine/resolve/resolvable.go
index c4d0830..797d4e2 100644
--- a/tmp/agent-patch-flux-pr-870.1-of-1.2026-02-28__13-38-10__gpt-5-1-codex-mini/app/v2/pkg/engine/resolve/resolvable.go
+++ b/app/v2/pkg/engine/resolve/resolvable.go
@@ -7,6 +7,7 @@ import (
"fmt"
"io"
+ "github.com/buger/jsonparser"
"github.com/goccy/go-json"
"github.com/cespare/xxhash/v2"
@@ -274,6 +275,9 @@ func (r *Resolvable) printTraceExtension(ctx context.Context, fetchTree *FetchTr
if err != nil {
return err
}
+ if normalized, err := normalizeJSON(content); err == nil {
+ content = normalized
+ }
r.printBytes(quote)
r.printBytes(literalTrace)
r.printBytes(quote)
@@ -282,6 +286,102 @@ func (r *Resolvable) printTraceExtension(ctx context.Context, fetchTree *FetchTr
return nil
}
+func normalizeJSON(data []byte) ([]byte, error) {
+ trimmed := bytes.TrimSpace(data)
+ if len(trimmed) == 0 {
+ return trimmed, nil
+ }
+ switch trimmed[0] {
+ case '{':
+ return normalizeJSONObject(trimmed)
+ case '[':
+ return normalizeJSONArray(trimmed)
+ default:
+ var buf bytes.Buffer
+ if err := json.Compact(&buf, trimmed); err != nil {
+ return nil, err
+ }
+ return buf.Bytes(), nil
+ }
+}
+
+func normalizeJSONObject(data []byte) ([]byte, error) {
+ var (
+ order []string
+ values = make(map[string][]byte)
+ )
+ err := jsonparser.ObjectEach(data, func(key []byte, value []byte, dataType jsonparser.ValueType, offset int) error {
+ keyStr := string(key)
+ normalizedValue, err := normalizeJSON(value)
+ if err != nil {
+ return err
+ }
+ if _, exists := values[keyStr]; exists {
+ for i, existingKey := range order {
+ if existingKey == keyStr {
+ order = append(order[:i], order[i+1:]...)
+ break
+ }
+ }
+ }
+ order = append(order, keyStr)
+ values[keyStr] = normalizedValue
+ return nil
+ })
+ if err != nil {
+ return nil, err
+ }
+ var buf bytes.Buffer
+ buf.WriteByte('{')
+ for i, key := range order {
+ if i != 0 {
+ buf.WriteByte(',')
+ }
+ keyBytes, err := json.Marshal(key)
+ if err != nil {
+ return nil, err
+ }
+ buf.Write(keyBytes)
+ buf.WriteByte(':')
+ buf.Write(values[key])
+ }
+ buf.WriteByte('}')
+ return buf.Bytes(), nil
+}
+
+func normalizeJSONArray(data []byte) ([]byte, error) {
+ var buf bytes.Buffer
+ buf.WriteByte('[')
+ first := true
+ var callbackErr error
+ if _, err := jsonparser.ArrayEach(data, func(value []byte, dataType jsonparser.ValueType, offset int, err error) {
+ if callbackErr != nil {
+ return
+ }
+ if err != nil {
+ callbackErr = err
+ return
+ }
+ normalizedValue, normErr := normalizeJSON(value)
+ if normErr != nil {
+ callbackErr = normErr
+ return
+ }
+ if !first {
+ buf.WriteByte(',')
+ }
+ first = false
+ buf.Write(normalizedValue)
+ }); err != nil {
+ return nil, err
+ }
+ if callbackErr != nil {
+ return nil, callbackErr
+ }
+ buf.WriteByte(']')
+ return buf.Bytes(), nil
+}
+
func (r *Resolvable) hasExtensions() bool {
if r.ctx.authorizer != nil && r.ctx.authorizer.HasResponseExtensionData(r.ctx) {
return true