refactor(schema): migrate from invopop/jsonschema to google/jsonschema-go#101
Draft
tak848 wants to merge 1 commit into
Draft
refactor(schema): migrate from invopop/jsonschema to google/jsonschema-go#101tak848 wants to merge 1 commit into
tak848 wants to merge 1 commit into
Conversation
…a-go
We only used invopop/jsonschema to generate JSON Schema from Go types
(editor config schemas + the LLM structured-output schema). Its
Schema.Properties is an ordered-map whose backing package invopop swaps
between releases (wk8 -> pb33f in v0.14), which broke our build because
config.go imported that package directly.
google/jsonschema-go is already in the dependency graph (via
anthropic-sdk-go -> modelcontextprotocol/go-sdk) and models property
order with a plain []string field instead of an ordered-map dependency,
so our code can never again be broken by an ordered-map swap. invopop /
pb33f remain in the build only as anthropic-sdk-go transitive deps; we
no longer import them directly.
Changes:
- config.go: build the provider.auth oneOf with google's Schema API,
exported as AuthConfigSchema (google has no custom-schema interface).
- genschema: reflect via jsonschema.For; collapse google's nullable
spelling ("type": ["null", T]) for pointers/slices back to the bare
type so the editor schema stays strict; overwrite provider.auth to
avoid the pointer-null widening making the oneOf unsatisfiable.
- LLM clients: build the output schema via jsonschema.For[llm.Output];
output is object + additionalProperties:false + all-required, matching
OpenAI strict mode. llm.Output tags: jsonschema_description -> jsonschema.
Regenerated schemas are semantically identical except provider.auth now
carries the description the code always intended (invopop dropped it).
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Why
We used
invopop/jsonschemaonly to generate JSON Schema from Go types — the editor config schemas (schemas/*.json) and the LLM structured-output schema. ItsSchema.Propertiesis an ordered-map whose backing package invopop swaps between releases (wk8/go-ordered-map→pb33f/ordered-mapin v0.14), which broke our build becauseconfig.goimported that package directly.What
Migrate all four schema-generation sites to
google/jsonschema-go, which is already in the dependency graph (viaanthropic-sdk-go→modelcontextprotocol/go-sdk) and models property order with a plain[]stringfield instead of an ordered-map dependency. Our code can no longer be broken by an ordered-map swap.invopop/pb33fstay in the build solely asanthropic-sdk-gotransitive deps; we no longer import them directly.config.go: build theprovider.authoneOfwith google'sSchemaAPI, exported asAuthConfigSchema()(google has no custom-schema interface, so the generator wires it in explicitly).genschema: reflect viajsonschema.For[config.Config]; collapse google's nullable spelling ("type": ["null", T], emitted for Go pointers/slices) back to the bare type so the editor schema stays strict; overwriteprovider.authto avoid the pointer-null widening making theoneOfunsatisfiable.jsonschema.For[llm.Output]; output isobject+additionalProperties:false+ all-required, matching OpenAI strict mode and Anthropic tool schema.llm.Outputstruct tags:jsonschema_description→jsonschema.Schema diff
Regenerated
schemas/*.jsonare semantically identical (verified by deep key-sorted comparison) exceptprovider.authnow carries thedescriptionthe code always intended —invopopsilently dropped it. Everything else is JSON key-order only.Verification
go build ./...,go vet ./...,go test -race -cover ./...all pass.invopop/jsonschema,pb33f/ordered-map, orwk8/go-ordered-mapremain.additionalProperties:false, all keys required, no$schema).