Skip to content

Align AI schema $ref pointer escaping with updated STJ behavior#7640

Closed
jozkee with Copilot wants to merge 3 commits into
mainfrom
copilot/fix-dollar-ref-encoding
Closed

Align AI schema $ref pointer escaping with updated STJ behavior#7640
jozkee with Copilot wants to merge 3 commits into
mainfrom
copilot/fix-dollar-ref-encoding

Conversation

Copilot AI commented Jul 17, 2026

Copy link
Copy Markdown
Contributor

System.Text.Json now percent-encodes JSON Pointer reference tokens when emitting $ref URI fragments. Our AI schema fix-up only applied ~0 / ~1 token escaping to the prepended parameter segment, which could produce under-encoded references inconsistent with the rest of the document.

  • Schema $ref alignment

    • Update EscapeJsonPointerSegment to match STJ's current behavior:
      1. RFC 6901 token-escape (~~0, /~1)
      2. URI-fragment percent-encode via Uri.EscapeDataString
    • Keep the existing $ref tail passthrough unchanged so exporter-produced inner pointer segments are not double-encoded.
  • Regression coverage

    • Keep the existing a/b~c case to verify slash/tilde token escaping remains stable.
    • Add a percent-encoding case in both affected test suites using hello%20world, asserting the emitted segment becomes hello%2520world.
  • Resulting behavior

    private static string EscapeJsonPointerSegment(string segment)
    {
        string escaped = segment.Replace("~", "~0").Replace("/", "~1");
        return Uri.EscapeDataString(escaped);
    }

    Example output change for a parameter named hello%20world:

    before: #/properties/hello%20world
    after:  #/properties/hello%2520world
    

Copilot AI changed the title [WIP] Fix $ref encoding to support percent-encoding Align AI schema $ref pointer escaping with updated STJ behavior Jul 17, 2026
Copilot AI requested a review from jozkee July 17, 2026 16:03
@jozkee
jozkee requested a review from Copilot July 17, 2026 16:03

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Updates AI JSON schema $ref generation so JSON Pointer reference-token escaping matches System.Text.Json’s current behavior by applying RFC 6901 token escaping followed by URI-fragment percent-encoding. This prevents under-encoded $ref fragments when parameter names contain %-style sequences.

Changes:

  • Updated EscapeJsonPointerSegment to token-escape (~//) and then percent-encode via Uri.EscapeDataString.
  • Added regression coverage asserting % sequences are double-encoded in $ref fragments (e.g., hello%20worldhello%2520world) in both impacted test suites.

Reviewed changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated 1 comment.

File Description
test/Libraries/Microsoft.Extensions.AI.Tests/Functions/AIFunctionFactoryTest.cs Adds regression test ensuring % in parameter names is percent-encoded in emitted $ref fragments.
test/Libraries/Microsoft.Extensions.AI.Abstractions.Tests/Utilities/AIJsonUtilitiesTests.cs Adds regression test for percent-encoding behavior in AIJsonUtilities.CreateFunctionJsonSchema.
src/Libraries/Microsoft.Extensions.AI.Abstractions/Utilities/AIJsonUtilities.Schema.Create.cs Updates JSON Pointer segment escaping to include URI percent-encoding after RFC 6901 token escaping.

@jozkee
jozkee marked this pull request as ready for review July 17, 2026 16:22
@jozkee
jozkee requested a review from a team as a code owner July 17, 2026 16:22
@jozkee
jozkee requested review from eiriktsarpalis and tarekgh July 17, 2026 16:25
@jozkee jozkee closed this Jul 17, 2026
@jozkee jozkee reopened this Jul 17, 2026
@tarekgh

tarekgh commented Jul 17, 2026

Copy link
Copy Markdown
Member

The percent-encoding here matches the JsonSchemaExporter change in dotnet/runtime#130164, but that change is on runtime main (11.0) and this repo still pins System.Text.Json at 9.0.18 / 10.0.10 / 8.0.6, none of which percent-encode yet.

So until an STJ build with #130164 flows in, the prepended #/properties/{param} segment gets percent-encoded while the exporter-produced tail segments (nested $refs into $defs, etc.) stay un-encoded. For a ref like #/properties/{param}/{tail} that is inconsistent whenever the tail also contains characters that need encoding.

The top-level property segment is fine on its own since it points at a raw property key and percent-encoding is the correct way to reference it, so real impact is limited to exotic names. But should we hold this until the STJ bump lands, or is there a reason to take it ahead of the dependency? Just want to make sure we don't ship a half-encoded pointer in the interim.

@jozkee

jozkee commented Jul 17, 2026

Copy link
Copy Markdown
Member

I thought it was fine to fix this ahead of time for MEAI, but I think the concern is valid. Let's wait until S.T.J ships #130164 and then conditionally align the fix with the STJ version — percent-encoding only when the runtime STJ also percent-encodes the exporter tail, so we don't ship a half-encoded pointer in the interim. Thanks.

@jozkee jozkee closed this Jul 17, 2026
@jozkee
jozkee deleted the copilot/fix-dollar-ref-encoding branch July 17, 2026 18:44
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants