Conversation
|
- Handle wildcard paths (e.g. "legs.*") in mergeObservedSelection so the schema observer sees the full field data - Add resolveSelectionsAgainstSchema to expand wildcards and bare leaf selections on object-typed fields in the generated GraphQL query - Remove disable: ["graphql"] from both sparse fieldset test scenarios Co-authored-by: aarne <82001+aarne@users.noreply.github.com>
Deploying with
|
| Status | Name | Latest Commit | Preview URL | Updated (UTC) |
|---|---|---|---|---|
| ✅ Deployment successful! View logs |
bridge | afccf1e | Commit Preview URL Branch Preview URL |
Mar 14 2026, 08:50 AM |
|
| Branch | copilot/finish-testing-harness-migration |
| Testbed | ubuntu-latest |
Click to view all benchmark results
| Benchmark | Latency | Benchmark Result nanoseconds (ns) (Result Δ%) | Upper Boundary nanoseconds (ns) (Limit %) |
|---|---|---|---|
| compiled: absolute baseline (passthrough, no tools) | 📈 view plot 🚷 view threshold | 0.00 ns(+1.64%)Baseline: 0.00 ns | 0.00 ns (92.98%) |
| compiled: array + SYNC tool-per-element 10 | 📈 view plot 🚷 view threshold | 0.01 ns(+3.47%)Baseline: 0.01 ns | 0.01 ns (91.06%) |
| compiled: array + SYNC tool-per-element 100 | 📈 view plot 🚷 view threshold | 0.02 ns(+4.95%)Baseline: 0.02 ns | 0.03 ns (82.09%) |
| compiled: array + tool-per-element 10 | 📈 view plot 🚷 view threshold | 0.01 ns(+11.81%)Baseline: 0.01 ns | 0.01 ns (91.03%) |
| compiled: array + tool-per-element 100 | 📈 view plot 🚷 view threshold | 0.04 ns(+13.89%)Baseline: 0.04 ns | 0.05 ns (87.04%) |
| compiled: chained 3-tool fan-out | 📈 view plot 🚷 view threshold | 0.01 ns(+15.46%)Baseline: 0.00 ns | 0.01 ns (96.94%) |
| compiled: flat array 10 items | 📈 view plot 🚷 view threshold | 0.01 ns(+12.65%)Baseline: 0.01 ns | 0.01 ns (93.66%) |
| compiled: flat array 100 items | 📈 view plot 🚷 view threshold | 0.02 ns(+26.91%)Baseline: 0.01 ns | 0.02 ns (83.49%) |
| compiled: flat array 1000 items | 📈 view plot 🚷 view threshold | 0.12 ns(+37.14%)Baseline: 0.09 ns | 0.16 ns (78.04%) |
| compiled: nested array 10x10 | 📈 view plot 🚷 view threshold | 0.03 ns(+20.47%)Baseline: 0.02 ns | 0.03 ns (87.53%) |
| compiled: nested array 20x10 | 📈 view plot 🚷 view threshold | 0.05 ns(+23.43%)Baseline: 0.04 ns | 0.05 ns (87.35%) |
| compiled: nested array 5x5 | 📈 view plot 🚷 view threshold | 0.01 ns(+15.15%)Baseline: 0.01 ns | 0.01 ns (91.26%) |
| compiled: short-circuit (overdefinition bypass) | 📈 view plot 🚷 view threshold | 0.00 ns(+1.53%)Baseline: 0.00 ns | 0.00 ns (92.94%) |
| compiled: simple chain (1 tool) | 📈 view plot 🚷 view threshold | 0.00 ns(+7.16%)Baseline: 0.00 ns | 0.00 ns (96.27%) |
| exec: absolute baseline (passthrough, no tools) | 📈 view plot 🚷 view threshold | 0.01 ns(+43.84%)Baseline: 0.00 ns | 0.01 ns (94.03%) |
| exec: array + SYNC tool-per-element 10 | 📈 view plot 🚷 view threshold | 0.11 ns(+8.16%)Baseline: 0.10 ns | 0.13 ns (81.93%) |
| exec: array + SYNC tool-per-element 100 | 📈 view plot 🚷 view threshold | 0.97 ns(+7.60%)Baseline: 0.90 ns | 1.19 ns (81.83%) |
| exec: array + tool-per-element 10 | 📈 view plot 🚷 view threshold | 0.12 ns(+37.58%)Baseline: 0.09 ns | 0.14 ns (89.52%) |
| exec: array + tool-per-element 100 | 📈 view plot 🚷 view threshold | 1.15 ns(+43.52%)Baseline: 0.80 ns | 1.23 ns (93.74%) |
| exec: chained 3-tool fan-out | 📈 view plot 🚷 view threshold | 0.05 ns(+108.95%)Baseline: 0.03 ns | 0.07 ns (82.47%) |
| exec: flat array 10 items | 📈 view plot 🚷 view threshold | 0.02 ns(+27.13%)Baseline: 0.02 ns | 0.02 ns (94.41%) |
| exec: flat array 100 items | 📈 view plot 🚷 view threshold | 0.10 ns(+21.13%)Baseline: 0.08 ns | 0.11 ns (92.16%) |
| exec: flat array 1000 items | 📈 view plot 🚷 view threshold | 0.87 ns(+19.62%)Baseline: 0.73 ns | 0.95 ns (91.34%) |
| exec: nested array 10x10 | 📈 view plot 🚷 view threshold | 0.16 ns(+21.19%)Baseline: 0.13 ns | 0.16 ns (95.66%) |
| exec: nested array 20x10 | 📈 view plot 🚷 view threshold | 0.30 ns(+20.18%)Baseline: 0.25 ns | 0.32 ns (95.94%) |
| exec: nested array 5x5 | 📈 view plot 🚷 view threshold | 0.06 ns(+22.75%)Baseline: 0.05 ns | 0.06 ns (96.27%) |
| exec: short-circuit (overdefinition bypass) | 📈 view plot 🚷 view threshold | 0.01 ns(+71.58%)Baseline: 0.00 ns | 0.01 ns (95.94%) |
| exec: simple chain (1 tool) | 📈 view plot 🚷 view threshold | 0.01 ns(+48.96%)Baseline: 0.01 ns | 0.01 ns (95.33%) |
| parse: large bridge (20 handles x 5 wires) | 📈 view plot 🚷 view threshold | 1.34 ns(+16.94%)Baseline: 1.14 ns | 1.60 ns (83.74%) |
| parse: simple bridge | 📈 view plot 🚷 view threshold | 0.04 ns(+2.99%)Baseline: 0.04 ns | 0.05 ns (77.70%) |
|
| Branch | copilot/finish-testing-harness-migration |
| Testbed | ubuntu-latest |
Click to view all benchmark results
| Benchmark | Latency | Benchmark Result nanoseconds (ns) (Result Δ%) | Upper Boundary nanoseconds (ns) (Limit %) |
|---|---|---|---|
| compiled: absolute baseline (passthrough, no tools) | 📈 view plot 🚷 view threshold | 0.00 ns(+4.26%)Baseline: 0.00 ns | 0.00 ns (95.38%) |
| compiled: array + SYNC tool-per-element 10 | 📈 view plot 🚷 view threshold | 0.01 ns(+4.16%)Baseline: 0.01 ns | 0.01 ns (91.66%) |
| compiled: array + SYNC tool-per-element 100 | 📈 view plot 🚷 view threshold | 0.02 ns(+3.46%)Baseline: 0.02 ns | 0.03 ns (80.93%) |
| compiled: array + tool-per-element 10 | 📈 view plot 🚷 view threshold | 0.01 ns(+12.41%)Baseline: 0.01 ns | 0.01 ns (91.52%) |
| compiled: array + tool-per-element 100 | 📈 view plot 🚷 view threshold | 0.04 ns(+15.30%)Baseline: 0.04 ns | 0.05 ns (88.12%) |
| compiled: chained 3-tool fan-out | 📈 view plot 🚷 view threshold | 0.01 ns(+17.13%)Baseline: 0.00 ns | 0.01 ns (98.34%) |
| compiled: flat array 10 items | 📈 view plot 🚷 view threshold | 0.01 ns(+12.65%)Baseline: 0.01 ns | 0.01 ns (93.66%) |
| compiled: flat array 100 items | 📈 view plot 🚷 view threshold | 0.02 ns(+27.27%)Baseline: 0.01 ns | 0.02 ns (83.72%) |
| compiled: flat array 1000 items | 📈 view plot 🚷 view threshold | 0.12 ns(+35.80%)Baseline: 0.09 ns | 0.16 ns (77.27%) |
| compiled: nested array 10x10 | 📈 view plot 🚷 view threshold | 0.03 ns(+21.05%)Baseline: 0.02 ns | 0.03 ns (87.96%) |
| compiled: nested array 20x10 | 📈 view plot 🚷 view threshold | 0.05 ns(+22.75%)Baseline: 0.04 ns | 0.05 ns (86.88%) |
| compiled: nested array 5x5 | 📈 view plot 🚷 view threshold | 0.01 ns(+15.32%)Baseline: 0.01 ns | 0.01 ns (91.39%) |
| compiled: short-circuit (overdefinition bypass) | 📈 view plot 🚷 view threshold | 0.00 ns(+3.61%)Baseline: 0.00 ns | 0.00 ns (94.85%) |
| compiled: simple chain (1 tool) | 📈 view plot 🚷 view threshold | 0.00 ns(+9.50%)Baseline: 0.00 ns | 0.00 ns (98.37%) |
| exec: absolute baseline (passthrough, no tools) | 📈 view plot 🚷 view threshold | 0.01 ns(+42.00%)Baseline: 0.00 ns | 0.01 ns (92.83%) |
| exec: array + SYNC tool-per-element 10 | 📈 view plot 🚷 view threshold | 0.11 ns(+7.82%)Baseline: 0.10 ns | 0.13 ns (81.67%) |
| exec: array + SYNC tool-per-element 100 | 📈 view plot 🚷 view threshold | 0.96 ns(+6.59%)Baseline: 0.90 ns | 1.19 ns (81.05%) |
| exec: array + tool-per-element 10 | 📈 view plot 🚷 view threshold | 0.12 ns(+37.55%)Baseline: 0.09 ns | 0.14 ns (89.50%) |
| exec: array + tool-per-element 100 | 📈 view plot 🚷 view threshold | 1.11 ns(+38.36%)Baseline: 0.80 ns | 1.23 ns (90.37%) |
| exec: chained 3-tool fan-out | 📈 view plot 🚷 view threshold | 0.05 ns(+109.27%)Baseline: 0.03 ns | 0.07 ns (82.59%) |
| exec: flat array 10 items | 📈 view plot 🚷 view threshold | 0.02 ns(+31.43%)Baseline: 0.02 ns | 0.02 ns (97.61%) |
| exec: flat array 100 items | 📈 view plot 🚷 view threshold | 0.10 ns(+28.28%)Baseline: 0.08 ns | 0.11 ns (97.60%) |
| exec: flat array 1000 items | 📈 view plot 🚷 view threshold | 0.91 ns(+25.90%)Baseline: 0.73 ns | 0.95 ns (96.13%) |
| exec: nested array 10x10 | 📈 view plot 🚷 view threshold | 0.16 ns(+22.23%)Baseline: 0.13 ns | 0.16 ns (96.48%) |
| exec: nested array 20x10 | 📈 view plot 🚷 view threshold | 0.31 ns(+21.48%)Baseline: 0.25 ns | 0.32 ns (96.98%) |
| exec: nested array 5x5 | 📈 view plot 🚷 view threshold | 0.06 ns(+23.75%)Baseline: 0.05 ns | 0.06 ns (97.06%) |
| exec: short-circuit (overdefinition bypass) | 📈 view plot 🚷 view threshold | 0.01 ns(+66.19%)Baseline: 0.00 ns | 0.01 ns (92.93%) |
| exec: simple chain (1 tool) | 📈 view plot 🚷 view threshold | 0.01 ns(+47.04%)Baseline: 0.01 ns | 0.01 ns (94.10%) |
| parse: large bridge (20 handles x 5 wires) | 📈 view plot 🚷 view threshold | 1.33 ns(+15.78%)Baseline: 1.14 ns | 1.60 ns (82.90%) |
| parse: simple bridge | 📈 view plot 🚷 view threshold | 0.04 ns(+4.02%)Baseline: 0.04 ns | 0.05 ns (78.47%) |
|
please add tests for the test harness also ... my undestanding of the field selector is field or field.subfield - is full selector (cascades to full sub object) the only way to represent this in graphql is JSOBObject shema for this test this field field.* or field.subfield.* - is shallow sub select of scalar values in this object please make sure we have a regressions test specifically for field selections. to make sure we have the full behaviour documented given this schema
fields: ["id", "legs.*"]will run a graphql query {id legs {a, b} } against the full generated schema fields: ["id", "legs"]will run a graphql query {id legs } against the schema where c output type is replaces with JSONObject |
- Wildcard (field.*) now selects only scalar sub-fields, not object-typed - Bare leaf (field) uses JSONObject schema replacement with standalone execution mode for correct pass-through behavior - Add buildScalarOnlySelectionTreeFromType for wildcard expansion - Add collectFieldsRequiringJSONObject and replaceFieldTypesWithJSONObject for per-scenario schema modification - Add field-selection-harness.test.ts with 10 tests documenting semantics - Include test/utils/*.test.ts in the test script Co-authored-by: aarne <82001+aarne@users.noreply.github.com>
Co-authored-by: aarne <82001+aarne@users.noreply.github.com>
Implemented in ef0e9bc and d6606c6. Field selection semantics are now:
Added
Also included |
Co-authored-by: aarne <82001+aarne@users.noreply.github.com>
Fix three bugs in ExecutionTree.response() for scalar-typed fields: 1. Array passthrough ([JSONObject]): skip shadow tree creation when the field is a pure passthrough with no element-level mappings. Shadow trees caused collectOutput() to materialise the wrong fields from the root bridge. 2. Shadow fallback ([JSONObject] in array-mapped output): return plain data instead of wrapping in shadow trees when scalar=true. 3. Structured sub-field (JSONObject): eagerly resolve nested field via resolveNestedField() instead of returning the ExecutionTree itself, which caused collectOutput() to materialise all output fields instead of just the sub-field. Remove the standalone execution workaround from the test harness. Add non-array object selection regression tests and focused GraphQL unit tests for JSONObject / [JSONObject] fields. Co-authored-by: aarne <82001+aarne@users.noreply.github.com>
Three bugs in
ExecutionTree.response()caused incorrect data materialisation for scalar-typed GraphQL fields (JSONObject,[JSONObject]). The test harness was masking these by forcing standalone execution mode whenever JSONObject schema replacement was needed.Bugs fixed in
ExecutionTree.response()[JSONObject]passthrough arrays — shadow tree creation causedcollectOutput()to resolve root-level output wires instead of returning element data. Fix: skip shadow trees for pure passthrough scalar arrays (no element-level mappings).[JSONObject]in array-mapped output — shadow fallback wrapped plain data in new shadow trees that couldn't resolve fields, producing{}. Fix: return plain array data whenscalar=true.JSONObjectstructured sub-fields —response()for path["legs"]with deeper wires at["legs","duration"]fell through toreturn this, thencollectOutput()materialised all output fields. Fix: eagerly resolve viaresolveNestedField(cleanPath).Test harness
executeBridgestandalone fallback fromregression.ts— JSONObject scenarios now exercise the full GraphQL resolver pathsparseObjPassthrough/sparseObjStructuredregression scenarios coveringlegs: JSONObject(non-array)jsonobject-fields.test.tswith 4 focused tests: single object passthrough, array passthrough, structured output, and array-mapped outputOriginal prompt
✨ Let Copilot coding agent set things up for you — coding agent works faster and does higher quality work when set up for your repo.