Skip to content

Conversation

@ranadeepsingh
Copy link
Collaborator

@ranadeepsingh ranadeepsingh commented Oct 14, 2025

Related Issues/PRs

feat: Add json_schema as responseFormat option #2428

What changes are proposed in this pull request?

  • Ensure json_schema response is ordered the way as specified. Ordering was being lost in the python dict -> scala Map conversion. Using ListMap instead now. Ordering of json_schema is important in cases like "chain of thought" prompting where a user might want the model to write "reason" before it gives "answer"
  • Let users only specify the schema part of json_schema and not type out the whole verbose dict/Map
  • Adding tests to ensure responseFormat output is ordered

How is this patch tested?

  • I have written tests (not required for typo or doc fix) and confirmed the proposed feature/bug-fix/change works.

Does this PR change any dependencies?

  • No. You can skip this section.
  • Yes. Make sure the dependencies are resolved correctly, and list changes here.

Does this PR add a new feature? If so, have you added samples on website?

  • No. You can skip this section.
  • Yes. Make sure you have added samples following below steps.
  1. Find the corresponding markdown file for your new feature in website/docs/documentation folder.
    Make sure you choose the correct class estimators/transformers and namespace.
  2. Follow the pattern in markdown file and add another section for your new API, including pyspark, scala (and .NET potentially) samples.
  3. Make sure the DocTable points to correct API link.
  4. Navigate to website folder, and run yarn run start to make sure the website renders correctly.
  5. Don't forget to add <!--pytest-codeblocks:cont--> before each python code blocks to enable auto-tests for python samples.
  6. Make sure the WebsiteSamplesTests job pass in the pipeline.

@ranadeepsingh
Copy link
Collaborator Author

/azp run

@azure-pipelines
Copy link

Azure Pipelines successfully started running 1 pipeline(s).

@codecov-commenter
Copy link

codecov-commenter commented Oct 14, 2025

Codecov Report

❌ Patch coverage is 83.33333% with 15 lines in your changes missing coverage. Please review.
✅ Project coverage is 84.46%. Comparing base (7aac49e) to head (6f72f1d).

Files with missing lines Patch % Lines
...napse/ml/services/openai/ResponseFormatUtils.scala 81.81% 10 Missing ⚠️
...ft/azure/synapse/ml/param/JsonEncodableParam.scala 0.00% 4 Missing ⚠️
...oft/azure/synapse/ml/param/UntypedArrayParam.scala 75.00% 1 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##           master    #2436      +/-   ##
==========================================
+ Coverage   84.41%   84.46%   +0.05%     
==========================================
  Files         333      334       +1     
  Lines       17550    17591      +41     
  Branches     1580     1603      +23     
==========================================
+ Hits        14815    14859      +44     
+ Misses       2735     2732       -3     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@ranadeepsingh
Copy link
Collaborator Author

/azp run

@azure-pipelines
Copy link

Azure Pipelines successfully started running 1 pipeline(s).

@ranadeepsingh
Copy link
Collaborator Author

/azp run

@azure-pipelines
Copy link

Azure Pipelines successfully started running 1 pipeline(s).

@ranadeepsingh
Copy link
Collaborator Author

/azp run

@azure-pipelines
Copy link

Azure Pipelines successfully started running 1 pipeline(s).

@ranadeepsingh
Copy link
Collaborator Author

/azp run

@azure-pipelines
Copy link

Azure Pipelines successfully started running 1 pipeline(s).

@ranadeepsingh
Copy link
Collaborator Author

/azp run

@azure-pipelines
Copy link

Azure Pipelines successfully started running 1 pipeline(s).

@ranadeepsingh
Copy link
Collaborator Author

/azp run

@azure-pipelines
Copy link

Azure Pipelines successfully started running 1 pipeline(s).

Copy link
Contributor

@mhamilton723 mhamilton723 left a comment

Choose a reason for hiding this comment

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

Minor things

@ranadeepsingh
Copy link
Collaborator Author

/azp run

@azure-pipelines
Copy link

Azure Pipelines successfully started running 1 pipeline(s).

@ranadeepsingh
Copy link
Collaborator Author

/azp run

@azure-pipelines
Copy link

Azure Pipelines successfully started running 1 pipeline(s).

@ranadeepsingh
Copy link
Collaborator Author

/azp run

@azure-pipelines
Copy link

Azure Pipelines successfully started running 1 pipeline(s).

@ranadeepsingh
Copy link
Collaborator Author

/azp run

@azure-pipelines
Copy link

Azure Pipelines successfully started running 1 pipeline(s).

@ranadeepsingh
Copy link
Collaborator Author

/azp run

@azure-pipelines
Copy link

Azure Pipelines successfully started running 1 pipeline(s).

@ranadeepsingh
Copy link
Collaborator Author

/azp run

@azure-pipelines
Copy link

Azure Pipelines successfully started running 1 pipeline(s).

@ranadeepsingh
Copy link
Collaborator Author

/azp run

@azure-pipelines
Copy link

Azure Pipelines successfully started running 1 pipeline(s).

@ranadeepsingh
Copy link
Collaborator Author

/azp run

@azure-pipelines
Copy link

Azure Pipelines successfully started running 1 pipeline(s).

@ranadeepsingh
Copy link
Collaborator Author

/azp run

@azure-pipelines
Copy link

Azure Pipelines successfully started running 1 pipeline(s).

)
if (value.contains("strict")) base + ("strict" -> value("strict")) else base
} else {
val js = value("json_schema").asInstanceOf[Map[String, Any]]
Copy link
Collaborator

Choose a reason for hiding this comment

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

Are we checking the type of json_schema upstream before we cast here? Consider pattern match instead

val hasSchema = value.contains("schema")
if (!hasName || !hasSchema) {
throw new IllegalArgumentException(
"Bare schema Map must include 'name' and 'schema' keys.")
Copy link
Collaborator

Choose a reason for hiding this comment

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

nit: consider indicating which keys have been specified and which are missing

js.get("strict").map(v => base ++ Map("strict" -> v)).getOrElse(base)
}
}
// Validation helpers moved into ResponseFormatUtils
Copy link
Collaborator

Choose a reason for hiding this comment

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

nit: unnecessary

if (hasFlat) {
val base = Map(
"type" -> "json_schema",
"name" -> value("name"),
Copy link
Collaborator

Choose a reason for hiding this comment

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

validation for name + schema?

if (value.contains("strict")) base + ("strict" -> value("strict")) else base
} else {
val js = value("json_schema").asInstanceOf[Map[String, Any]]
val name = js.getOrElse("name",
Copy link
Collaborator

Choose a reason for hiding this comment

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

does this validate that name/schema is nonempty/nonnull or just that the keys exist?

throw new IllegalArgumentException(
"json_schema requires nested 'json_schema' or top-level 'name' and 'schema'.")
}
if (hasFlat) {
Copy link
Collaborator

Choose a reason for hiding this comment

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

Should we error/alert if the user erroneously specifies both json_schema + name/schema?

val payload =
if (normalized.get("type").exists(_.toString.equalsIgnoreCase("json_schema"))) {
Map(
"type" -> "json_schema",
Copy link
Collaborator

Choose a reason for hiding this comment

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

nit: consider elevating "json_schema" "name" and "schema" to vals to reduce duplication and avoid potential typo errors if any of these strings need to be updated in the future

@ranadeepsingh ranadeepsingh merged commit fc6675d into microsoft:master Oct 24, 2025
69 of 70 checks passed
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