agentic-aeson 0.2.0.3 → 0.2.0.4
raw patch · 3 files changed
+22/−18 lines, 3 filesPVP ok
version bump matches the API change (PVP)
API changes (from Hackage documentation)
Files
- CHANGELOG.md +4/−0
- agentic-aeson.cabal +2/−2
- src/Agentic/JsonSchema.hs +16/−16
CHANGELOG.md view
@@ -1,5 +1,9 @@ # Changelog for agentic-aeson +## 0.2.0.4 - 2026-10-06++* Follows agentic's record field changes; no API change.+ ## 0.2.0.3 - 2026-10-06 * No changes; released alongside agentic 0.2.0.3.
agentic-aeson.cabal view
@@ -1,6 +1,6 @@ cabal-version: 3.0 name: agentic-aeson-version: 0.2.0.3+version: 0.2.0.4 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.@@ -23,7 +23,7 @@ library default-language: GHC2021- default-extensions: LambdaCase OverloadedStrings+ default-extensions: DuplicateRecordFields LambdaCase NoFieldSelectors OverloadedRecordDot OverloadedStrings ghc-options: -Wall hs-source-dirs: src exposed-modules:
src/Agentic/JsonSchema.hs view
@@ -30,23 +30,23 @@ -- | Like 'jsonSchema', but any schema named in @shared@ becomes a @$ref@ into -- @$defs@. schemaWith :: [Text] -> Schema -> Value-schemaWith shared s = case title s of+schemaWith shared s = case s.title of Just t | t `elem` shared -> Object [("$ref", String ("#/$defs/" <> t))] _ -> definition shared s -- | A schema written out, though the schemas inside it may still be references. definition :: [Text] -> Schema -> Value-definition shared s = withDescription (body (shape s))+definition shared s = withDescription (body s.shape) where sub = schemaWith shared withDescription = \case Object kvs | Just d <- description -> Object (kvs <> [("description", String d)]) v -> v- description = case catMaybes [doc s] <> map (\c -> "Must be " <> c <> ".") (checks s) of+ description = case catMaybes [s.doc] <> map (\c -> "Must be " <> c <> ".") s.checks of [] -> Nothing ds -> Just (T.intercalate " " ds) body = \case- SObject fs -> object (map (\f -> (fieldName f, sub (fieldSchema f))) fs)+ SObject fs -> object (map (\f -> (f.name, sub f.schema)) fs) SSum vs -> Object [("anyOf", Array (map variant vs))] SEnum ls | all ((== Nothing) . snd) ls -> Object [typed "string", ("enum", Array (map (String . fst) ls))]@@ -59,9 +59,9 @@ SBool -> Object [typed "boolean"] SNull -> Object [typed "null"] variant v =- let tagged = ("tag", Object [typed "string", ("const", String (variantTag v))])- o = object (tagged : map (\f -> (fieldName f, sub (fieldSchema f))) (variantFields v))- in case (o, variantDoc v) of+ let tagged = ("tag", Object [typed "string", ("const", String v.tag)])+ o = object (tagged : map (\f -> (f.name, sub f.schema)) v.fields)+ in case (o, v.doc) of (Object kvs, Just d) -> Object (kvs <> [("description", String d)]) _ -> o constant l d = Object ([typed "string", ("const", String l)] <> maybe [] (\t -> [("description", String t)]) d)@@ -87,7 +87,7 @@ -- | Does this schema need wrapping to be a top-level object? wrap :: Schema -> Bool-wrap s = case shape s of+wrap s = case s.shape of SObject _ -> False _ -> True @@ -107,24 +107,24 @@ | otherwise = definition shared s shared = sharedNames s defs = [(t, definition shared d) | t <- shared, Just d <- [lookup t named']]- named' = [(t, d) | d <- nested s, Just t <- [title d]]+ named' = [(t, d) | d <- nested s, Just t <- [d.title]] -- | 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. sharedNames :: Schema -> [Text]-sharedNames s = [t | t <- nub names, uses t >= 2, length (nub [d | d <- inside, title d == Just t]) == 1]+sharedNames s = [t | t <- nub names, uses t >= 2, length (nub [d | d <- inside, d.title == Just t]) == 1] where inside = nested s- names = catMaybes (map title inside)- uses t = length (filter ((== Just t) . title) inside)+ names = catMaybes (map (.title) inside)+ uses t = length (filter ((== Just t) . (.title)) inside) -- | Every schema nested inside this one, outermost first. nested :: Schema -> [Schema]-nested s = concatMap (\c -> c : nested c) (children (shape s))+nested s = concatMap (\c -> c : nested c) (children s.shape) where children = \case- SObject fs -> map fieldSchema fs- SSum vs -> concatMap (map fieldSchema . variantFields) vs+ SObject fs -> map (.schema) fs+ SSum vs -> concatMap (map (.schema) . (.fields)) vs SArray c -> [c] SNullable c -> [c] _ -> []@@ -132,7 +132,7 @@ -- | A name for the schema, for providers that ask for one: the type's name with -- anything but letters, digits, @_@ and @-@ dropped, or @output@. schemaName :: Schema -> Text-schemaName s = case T.intercalate "_" (filter (not . T.null) (T.split (not . valid) (maybe "" id (title s)))) of+schemaName s = case T.intercalate "_" (filter (not . T.null) (T.split (not . valid) (maybe "" id s.title))) of "" -> "output" n -> T.take 64 n where