packages feed

agentic-openai 0.2.0.5 → 0.2.1.0

raw patch · 4 files changed

+46/−15 lines, 4 filesdep ~agenticdep ~agentic-aesondep ~agentic-ioPVP ok

version bump matches the API change (PVP)

Dependency ranges changed: agentic, agentic-aeson, agentic-io, agentic-openai

API changes (from Hackage documentation)

Files

CHANGELOG.md view
@@ -1,5 +1,10 @@ # Changelog for agentic-openai +## 0.2.1.0 - 2026-11-06++* Follow Agentic's `Structure`/`Outline` API and fallible model compilation.+  Provider wire schemas and protocols are unchanged.+ ## 0.2.0.5 - 2026-10-06  * No changes; released alongside agentic 0.2.0.5.
agentic-openai.cabal view
@@ -1,6 +1,6 @@ cabal-version:      3.0 name:               agentic-openai-version:            0.2.0.5+version:            0.2.1.0 synopsis:           OpenAI as the System Two provider for agentic description:   Runs agentic's draft steps on OpenAI models through the Responses API, with strict structured outputs and tools, and can stand in as System One.@@ -38,8 +38,8 @@   hs-source-dirs:   src   exposed-modules:  Agentic.OpenAI   build-depends:-    , agentic          ==0.2.*-    , agentic-aeson    ==0.2.*+    , agentic          >=0.2.1 && <0.3+    , agentic-aeson    >=0.2.1 && <0.3     , aeson            >=2.1 && <2.3     , base             >=4.18 && <5     , bytestring       >=0.11 && <0.13@@ -53,9 +53,9 @@   hs-source-dirs:   test   main-is:          Spec.hs   build-depends:-    , agentic          ==0.2.*-    , agentic-aeson    ==0.2.*-    , agentic-openai   ==0.2.*+    , agentic          >=0.2.1 && <0.3+    , agentic-aeson    >=0.2.1 && <0.3+    , agentic-openai   >=0.2.1 && <0.3     , aeson            >=2.1 && <2.3     , base             >=4.18 && <5     , hspec            >=2.10 && <3@@ -67,9 +67,9 @@   hs-source-dirs:   test-live   main-is:          Live.hs   build-depends:-    , agentic          ==0.2.*-    , agentic-openai   ==0.2.*-    , agentic-io       ==0.2.*+    , agentic          >=0.2.1 && <0.3+    , agentic-openai   >=0.2.1 && <0.3+    , agentic-io       >=0.2.1 && <0.3     , base             >=4.18 && <5     , hspec            >=2.10 && <3     , text             >=2.0 && <2.2
test-live/Live.hs view
@@ -29,13 +29,13 @@       "How much the audience groans"       [option Mild "A polite smile", option Solid "An audible groan", option Unbearable "People get up and leave"] -deriving via Enumeration Groan instance Contract Groan+instance Contract Groan where contract = enumeration  newtype Rating = Rating Int   deriving (Show, Eq)  instance Contract Rating where-  contract = mapCodec Rating (\(Rating n) -> n) (between 1 10 contract)+  contract = mapStructure Rating (\(Rating n) -> n) (between 1 10 contract)  main :: IO () main = do
test/Spec.hs view
@@ -1,8 +1,10 @@ module Main (main) where  import Agentic+import Agentic.Scripted (modelContract) import Agentic.Runtime (Conversation (..))-import Agentic.Schema (Shape (..))+import Agentic.Schema (Schema(..), Field(..), Shape (..))+import Agentic.JsonSchema (objectSchema) import Agentic.Aeson (toAeson) import Agentic.OpenAI import qualified Data.Aeson as J@@ -22,6 +24,9 @@ data Board = Board {top :: Row, middle :: Row, bottom :: Row}   deriving (Generic, Show, Contract) +data Box a = Box { value :: a } deriving (Generic, Contract)+data Repeated = Repeated { one :: Box Int, two :: Box Int } deriving (Generic, Contract)+ conversation :: Conversation conversation =   Conversation@@ -29,8 +34,8 @@     , instruction = "Suggest 3 dinosaurs"     , input = Null     , inputSchema = schemaOf SNull-    , tools = [ToolSpec "search" "Search the fossil database" ((contract @Text).schema)]-    , outputSchema = (contract @[Text]).schema+    , tools = [ToolSpec "search" "Search the fossil database" ((modelContract @Text).schema)]+    , outputSchema = (modelContract @[Text]).schema     , history = []     } @@ -57,11 +62,32 @@         )    it "names the schema after its type, and shares repeated types through $defs" $ do-    let format = at "format" (at "text" (body conversation {outputSchema = (contract @Board).schema}))+    let format = at "format" (at "text" (body conversation {outputSchema = (modelContract @Board).schema}))         schema = at "schema" format     at "name" format `shouldBe` J.String "Board"     at "top" (at "properties" schema) `shouldBe` fromJust (J.decode "{\"$ref\":\"#/$defs/Row\"}")     KeyMap.keys (case at "$defs" schema of J.Object o -> o; _ -> mempty) `shouldMatchList` ["Row", "Square"]++  it "uses safe shared-definition keys for applied type names" $ do+    let schema = toAeson (objectSchema (modelContract @Repeated).schema)+    at "$ref" (at "one" (at "properties" schema)) `shouldBe` J.String "#/$defs/Box_Int"+    at "$ref" (at "two" (at "properties" schema)) `shouldBe` J.String "#/$defs/Box_Int"+    at "type" (at "Box_Int" (at "$defs" schema)) `shouldBe` J.String "object"++  it "keeps colliding sanitized names and pointer punctuation distinct" $ do+    let a = Schema (Just "Box Int") Nothing [] SInteger+        b = Schema (Just "Box_Int") Nothing [] (SString Nothing)+        c = Schema (Just "A/B~C") Nothing [] SBool+        root = schemaOf (SObject [Field n ty True | (n, ty) <- [("a1",a),("a2",a),("b1",b),("b2",b),("c1",c),("c2",c)]])+        schema = toAeson (objectSchema root)+        defs = at "$defs" schema+        props = at "properties" schema+    at "$ref" (at "a1" props) `shouldBe` J.String "#/$defs/Box_Int"+    at "$ref" (at "b1" props) `shouldBe` J.String "#/$defs/Box_Int_2"+    at "$ref" (at "c1" props) `shouldBe` J.String "#/$defs/A_B_C"+    at "type" (at "Box_Int" defs) `shouldBe` J.String "integer"+    at "type" (at "Box_Int_2" defs) `shouldBe` J.String "string"+    at "type" (at "A_B_C" defs) `shouldBe` J.String "boolean"    it "stores nothing, and asks for reasoning it can send back" $ do     at "store" (body conversation) `shouldBe` J.Bool False