Skip to content

Make JSONValue an AnyLanguageModel type - #267

Draft
mattt wants to merge 3 commits into
mainfrom
mattt/own-jsonvalue
Draft

mattt wants to merge 3 commits into
mainfrom
mattt/own-jsonvalue

Conversation

@mattt

@mattt mattt commented Sep 25, 2026

Copy link
Copy Markdown
Collaborator

JSONValue is a typealias for JSONSchema's JSONValue, so every public API that uses it ties AnyLanguageModel's major version to JSONSchema's. That covers extraBody on the OpenAI, Open Responses, and Anthropic options, MLX additionalContext, Ollama's CustomGenerationOptions, and GeneratedContent.init(_: JSONValue) and GeneratedContent.jsonValue from #257.

This PR replaces the typealias with AnyLanguageModel's own JSONValue enum. It has the same seven cases, codes as plain JSON, and conforms to Sendable, Hashable, Codable, and the nil, Boolean, integer, float, string, array, and dictionary literal protocols, so literals like extraBody: ["user": "id"] keep compiling. It keeps init(_:) for Encodable values and JSONSchema's accessors (isNull, boolValue, intValue, doubleValue, stringValue, arrayValue, and objectValue) with the same behavior. Internally, it converts to and from JSONSchema's type where the package reads a schema.

This is source-breaking in two ways. Code that uses the rest of JSONSchema's JSONValue API on these values no longer compiles: description, string interpolation literals, isCompatible(with:strict:), and the String, Int, Double, and Bool initializers that take a JSONValue. And a file that imports both AnyLanguageModel and JSONSchema now sees two JSONValue types and needs to write AnyLanguageModel.JSONValue or JSONSchema.JSONValue.

JSONValue was a typealias for the JSONSchema package's JSONValue, so
every public API that takes or returns one tied AnyLanguageModel's
major version to JSONSchema's. That includes extraBody on the OpenAI,
Open Responses, and Anthropic options, MLX additionalContext, Ollama's
custom options, and the GeneratedContent JSONValue initializer and
property.

Define JSONValue as AnyLanguageModel's own enum with the same cases,
plain JSON coding, and literal conformances, so dictionary literals
passed to these APIs keep compiling. It keeps the Encodable initializer
and objectValue, which the package already uses, and drops the other
JSONSchema conveniences. Values read from a JSONSchema are converted at
the point of use.

Code that imports both AnyLanguageModel and JSONSchema now has two
JSONValue types and must qualify the name.
The new JSONValue kept only objectValue from JSONSchema's accessors, so
code that read values through isNull, boolValue, intValue, doubleValue,
stringValue, or arrayValue stopped compiling.

Add those accessors with JSONSchema's semantics: intValue returns nil
for a double, and doubleValue converts an int.

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Copilot review overview

🟡 Changes recommended

The replacement should remain frozen to avoid an additional source break for library-evolution clients.

Get a fresh assessment by requesting another Copilot review.

Review effort: Balanced
Findings: 1 Medium severity

Open (1)
What changed in this PR

Introduces an AnyLanguageModel-owned JSONValue, decoupling public APIs from JSONSchema’s major version.

Changes:

  • Adds the public JSON value enum, literals, Codable support, and accessors.
  • Adds internal conversion to and from JSONSchema values.
  • Updates schema integrations and provides comprehensive tests.
File Description
Sources/​AnyLanguageModel/​Shared/​JSONValue.swift Defines the new public JSON value type.
Sources/​AnyLanguageModel/​Shared/​JSONValue+JSONSchema.swift Bridges internal JSONSchema values.
Sources/​AnyLanguageModel/​Models/​SystemLanguageModel.swift Converts schema enum values through the bridge.
Sources/​AnyLanguageModel/​Models/​LlamaLanguageModel.swift Encodes JSONSchema enum arrays directly.
Sources/​AnyLanguageModel/​Models/​CoreMLLanguageModel.swift Encodes JSONSchema enum arrays directly.
Tests/​AnyLanguageModelTests/​JSONValueTests.swift Tests coding, literals, accessors, and conversion.
Tests/​AnyLanguageModelTests/​DynamicSchemaConversionTests.swift Narrows the JSONSchema import.
Tests/​AnyLanguageModelTests/​OpenAILanguageModelTests.swift Removes the unnecessary JSONSchema import.
Tests/​AnyLanguageModelTests/​ConvertibleToGeneratedContentTests.swift Removes the unnecessary JSONSchema import.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread Sources/AnyLanguageModel/Shared/JSONValue.swift Outdated
JSONSchema's JSONValue is frozen, so clients built with library
evolution can switch over its cases exhaustively. Keep that for the
replacement, since JSON has a fixed set of seven kinds of value.
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.

2 participants