agentic-aeson 0.2.0.5 → 0.2.1.0
raw patch · 3 files changed
+32/−9 lines, 3 filesdep ~agenticPVP ok
version bump matches the API change (PVP)
Dependency ranges changed: agentic
API changes (from Hackage documentation)
Files
- CHANGELOG.md +6/−0
- agentic-aeson.cabal +2/−2
- src/Agentic/JsonSchema.hs +24/−7
CHANGELOG.md view
@@ -1,5 +1,11 @@ # Changelog for agentic-aeson +## 0.2.1.0 - 2026-11-06++* Follow Agentic's `Structure`/`Outline` API and fallible model compilation.+ Shared definition keys now sanitize applied type names and allocate distinct+ keys when different names sanitize or truncate to the same spelling.+ ## 0.2.0.5 - 2026-10-06 * No changes; released alongside agentic 0.2.0.5.
agentic-aeson.cabal view
@@ -1,6 +1,6 @@ cabal-version: 3.0 name: agentic-aeson-version: 0.2.0.5+version: 0.2.1.0 synopsis: Conversions between agentic's values and aeson, and strict JSON Schema description: Shared by the agentic provider packages: converts the core's Value to and from aeson, and lowers contracts to the strict JSON Schema that providers' structured outputs accept, keeping field order and sharing repeated types through $defs.@@ -30,7 +30,7 @@ Agentic.Aeson Agentic.JsonSchema build-depends:- , agentic ==0.2.*+ , agentic >=0.2.1 && <0.3 , aeson >=2.1 && <2.3 , base >=4.18 && <5 , scientific >=0.3 && <0.4
src/Agentic/JsonSchema.hs view
@@ -29,13 +29,13 @@ -- | Like 'jsonSchema', but any schema named in @shared@ becomes a @$ref@ into -- @$defs@.-schemaWith :: [Text] -> Schema -> Value+schemaWith :: [(Text, Text)] -> Schema -> Value schemaWith shared s = case s.title of- Just t | t `elem` shared -> Object [("$ref", String ("#/$defs/" <> t))]+ Just t | Just key <- lookup t shared -> Object [("$ref", String ("#/$defs/" <> key))] _ -> definition shared s -- | A schema written out, though the schemas inside it may still be references.-definition :: [Text] -> Schema -> Value+definition :: [(Text, Text)] -> Schema -> Value definition shared s = withDescription (body s.shape) where sub = schemaWith shared@@ -95,8 +95,8 @@ -- object with a single @value@ field holding it. A named type that appears more -- than once, identically, is written once under @$defs@ and referenced. ----- TBD: Recursively defined schemas will hang here. A recursive type's derived--- schema contains itself, so walking it never ends.+-- Input schemas must be finite. Contract discovery and compilation have the+-- same restriction. objectSchema :: Schema -> Value objectSchema s = case root of Object kvs | not (null defs) -> Object (kvs <> [("$defs", Object defs)])@@ -105,9 +105,26 @@ root | wrap s = object [("value", schemaWith shared s)] | otherwise = definition shared s- shared = sharedNames s- defs = [(t, definition shared d) | t <- shared, Just d <- [lookup t named']]+ shared = definitionKeys (sharedNames s)+ defs = [(key, definition shared d) | (t, key) <- shared, Just d <- [lookup t named']] named' = [(t, d) | d <- nested s, Just t <- [d.title]]++-- Applied type names contain punctuation. Allocate safe definition keys without+-- conflating names that sanitize to the same spelling (or truncate equally).+definitionKeys :: [Text] -> [(Text, Text)]+definitionKeys = go []+ where+ go _ [] = []+ go used (name:names) =+ let base = schemaName (Schema (Just name) Nothing [] SNull)+ key = fresh used base 1+ in (name, key) : go (key:used) names+ fresh used base n+ | key `elem` used = fresh used base (n + 1)+ | otherwise = key+ where+ suffix = "_" <> T.pack (show (n :: Integer))+ key = if n == 1 then base else T.take (64 - T.length suffix) base <> suffix -- | Names of the types inside a schema (not the schema itself) that appear more -- than once and are identical everywhere they appear, in order of appearance.