packages feed

openai 2.0.0 → 2.1.0

raw patch · 4 files changed

+77/−7 lines, 4 files

Files

CHANGELOG.md view
@@ -1,3 +1,7 @@+2.1.0:++- Add `Item_Input_Reasoning` constructor and JSON round-trip test so reasoning traces from tool calls can be echoed back via the Responses API.+ 2.0.0:  - **BREAKING CHANGE**: Renamed `Item_InputMessage` to `Item_Input_Message` in `OpenAI.V1.Responses` for consistency with new constructors
openai.cabal view
@@ -1,6 +1,6 @@ cabal-version:      2.4 name:               openai-version:            2.0.0+version:            2.1.0 synopsis:           Servant bindings to OpenAI description:        This package provides comprehensive and type-safe bindings                     to OpenAI, providing both a Servant interface and
src/OpenAI/V1/Responses.hs view
@@ -74,7 +74,7 @@  -- | Role of an input message data InputRole = User | System | Developer-    deriving stock (Generic, Show)+    deriving stock (Eq, Generic, Show)  instance FromJSON InputRole where     parseJSON = genericParseJSON aesonOptions@@ -88,7 +88,7 @@     | Input_Image { image_url :: Maybe Text, file_id :: Maybe Text, detail :: Maybe Text }     | Input_File { file_id :: Maybe Text, filename :: Maybe Text, file_url :: Maybe Text, file_data :: Maybe Text }     | Input_Audio { input_audio :: Object }-    deriving stock (Generic, Show)+    deriving stock (Eq, Generic, Show)  inputContentOptions :: Options inputContentOptions =@@ -125,10 +125,17 @@         , output :: Text         , status :: Maybe Text         }+    | Item_Input_Reasoning+        { reasoning_id :: Text+        , reasoning_encrypted_content :: Maybe Text+        , reasoning_summary :: Maybe (Vector SummaryPart)+        , reasoning_content :: Maybe (Vector ReasoningText)+        , reasoning_status :: Maybe Text+        }     | Item_Input_Item_Reference         { id :: Maybe Text         }-    deriving stock (Generic, Show)+    deriving stock (Eq, Generic, Show)  inputItemOptions :: Options inputItemOptions =@@ -136,6 +143,7 @@         { sumEncoding = TaggedObject{ tagFieldName = "type", contentsFieldName = "" }         , tagSingleConstructors = True         , constructorTagModifier = stripPrefix "Item_Input_"+        , fieldLabelModifier = stripPrefix "reasoning_"         }  instance FromJSON InputItem where@@ -491,7 +499,7 @@  -- | Reasoning summary part data SummaryPart = Summary_Text{ text :: Text }-    deriving stock (Generic, Show)+    deriving stock (Eq, Generic, Show)  summaryPartOptions :: Options summaryPartOptions = aesonOptions@@ -507,7 +515,7 @@  -- | Reasoning text part data ReasoningText = Reasoning_Text{ text :: Text }-    deriving stock (Generic, Show)+    deriving stock (Eq, Generic, Show)  reasoningTextOptions :: Options reasoningTextOptions = aesonOptions@@ -528,7 +536,7 @@     , summary :: Maybe (Vector SummaryPart)     , content :: Maybe (Vector ReasoningText)     , status :: Maybe Text-    } deriving stock (Generic, Show)+    } deriving stock (Eq, Generic, Show)  instance FromJSON ReasoningItem where     parseJSON = genericParseJSON aesonOptions
tasty/Main.hs view
@@ -5,6 +5,8 @@  module Main where +import Data.Aeson ((.=))+import qualified Data.Aeson as Aeson import Control.Exception (SomeException, catch) import OpenAI.V1 (Methods(..)) import OpenAI.V1.Audio.Speech (CreateSpeech(..), Voice(..), _CreateSpeech)@@ -975,6 +977,61 @@            return () +  let responsesReasoningInputSerializationTest =+        HUnit.testCase "Responses - reasoning input serialization" do+          let reasoningItem =+                Responses.Item_Input_Reasoning+                  { Responses.reasoning_id = "reasoning_123"+                  , Responses.reasoning_encrypted_content = Just "ciphertext"+                  , Responses.reasoning_summary =+                      Just+                        [ Responses.Summary_Text+                            { Responses.text = "High-level plan" }+                        ]+                  , Responses.reasoning_content =+                      Just+                        [ Responses.Reasoning_Text+                            { Responses.text = "Step 1: inspect tool output." }+                        ]+                  , Responses.reasoning_status = Just Responses.statusCompleted+                  }+              encoded = Aeson.encode reasoningItem+              expected :: Aeson.Value+              expected =+                Aeson.object+                  [ "type" .= ("reasoning" :: Text.Text)+                  , "id" .= ("reasoning_123" :: Text.Text)+                  , "encrypted_content" .= ("ciphertext" :: Text.Text)+                  , "summary"+                      .= ( [ Aeson.object+                                [ "type" .= ("summary_text" :: Text.Text)+                                , "text" .= ("High-level plan" :: Text.Text)+                                ]+                            ]+                         :: [Aeson.Value]+                         )+                  , "content"+                      .= ( [ Aeson.object+                                [ "type" .= ("reasoning_text" :: Text.Text)+                                , "text" .= ("Step 1: inspect tool output." :: Text.Text)+                                ]+                            ]+                         :: [Aeson.Value]+                         )+                  , "status" .= (Responses.statusCompleted :: Text.Text)+                  ]+          case Aeson.decode encoded of+            Nothing ->+              HUnit.assertFailure "Failed to decode encoded reasoning input item"+            Just decodedValue ->+              HUnit.assertEqual "Encoded JSON mismatch" expected decodedValue++          case Aeson.fromJSON expected of+            Aeson.Error err ->+              HUnit.assertFailure ("Round-trip decode failed: " <> err)+            Aeson.Success decoded ->+              HUnit.assertEqual "Round-trip mismatch" reasoningItem decoded+   let tests =           speechTests             <> [ transcriptionTest,@@ -994,6 +1051,7 @@                createImageVariationMaximalTest,                createModerationTest,                responsesMinimalTest,+               responsesReasoningInputSerializationTest,                responsesStreamingHaikuTest,                responsesCodeInterpreterStreamingTest,                assistantsTest,