baikai-openai 0.3.0.1 → 0.3.0.2
raw patch · 6 files changed
+80/−10 lines, 6 filesdep ~baikaiPVP ok
version bump matches the API change (PVP)
Dependency ranges changed: baikai
API changes (from Hackage documentation)
Files
- baikai-openai.cabal +3/−3
- src/Baikai/Provider/OpenAI/Interactive.hs +11/−0
- src/Baikai/Provider/OpenAI/Internal/Request.hs +4/−0
- src/Baikai/Provider/OpenAI/Shape.hs +12/−7
- test/Main.hs +21/−0
- test/ShapeSpec.hs +29/−0
baikai-openai.cabal view
@@ -1,6 +1,6 @@ cabal-version: 3.4 name: baikai-openai-version: 0.3.0.1+version: 0.3.0.2 synopsis: OpenAI providers for the baikai abstraction description: Wraps the openai Haskell package as a Baikai Provider for OpenAI's Chat Completions API.@@ -42,7 +42,7 @@ build-depends: , aeson ^>=2.2- , baikai ^>=0.3.0+ , baikai ^>=0.4.0 , base >=4.20 && <5 , base64-bytestring ^>=1.2 , bytestring ^>=0.12@@ -76,7 +76,7 @@ build-depends: , aeson- , baikai ^>=0.3.0+ , baikai ^>=0.4.0 , baikai-openai , base >=4.20 && <5 , bytestring
src/Baikai/Provider/OpenAI/Interactive.hs view
@@ -29,6 +29,7 @@ ) import Baikai.Prelude import Baikai.Provider.Cli.Internal qualified as Internal+import Baikai.ThinkingLevel (renderThinkingLevel) import Data.Generics.Labels () import Data.Text qualified as Text import System.Process qualified as P@@ -54,6 +55,7 @@ codexInteractiveCommand cfg req = ( cfg ^. #executable, modelArgs req+ <> effortArgs req <> workingDirArgs req <> extraDirArgs req <> safetyArgs req@@ -90,6 +92,15 @@ Nothing -> [] Just "" -> [] Just mid -> ["--model", Text.unpack mid]++-- | Codex receives reasoning effort through a config override. The+-- provider-only @none@ and @ultra@ values remain available through+-- raw extra arguments.+effortArgs :: InteractiveLaunchRequest -> [String]+effortArgs req = case req ^. #effort of+ Nothing -> []+ Just lvl ->+ ["-c", "model_reasoning_effort=" <> Text.unpack (renderThinkingLevel lvl)] workingDirArgs :: InteractiveLaunchRequest -> [String] workingDirArgs req = case req ^. #workingDir of
src/Baikai/Provider/OpenAI/Internal/Request.hs view
@@ -127,6 +127,10 @@ ThinkingLow -> Chat.ReasoningEffort_Low ThinkingMedium -> Chat.ReasoningEffort_Medium ThinkingHigh -> Chat.ReasoningEffort_High+ -- The SDK enum stops at High. Shape.injectThinkingShape restores+ -- the canonical xhigh/max string in the serialized native OpenAI body.+ ThinkingXHigh -> Chat.ReasoningEffort_High+ ThinkingMax -> Chat.ReasoningEffort_High -- | Map a baikai 'Tool.Tool' into the upstream OpenAI 'Tool_Function' -- shape. The compat record's 'supportsStrictMode' flag controls
src/Baikai/Provider/OpenAI/Shape.hs view
@@ -26,7 +26,7 @@ ThinkingFormat (..), ) import Baikai.Options (Options, cacheRetention, thinking)-import Baikai.ThinkingLevel (ThinkingLevel (..))+import Baikai.ThinkingLevel (ThinkingLevel (..), renderThinkingLevel) import Data.Aeson (Value (..), (.=)) import Data.Aeson qualified as Aeson import Data.Aeson.Key qualified as AesonKey@@ -92,15 +92,16 @@ case thinking opts of Nothing -> body Just lvl -> case thinkingFormat compat of- ThinkingFormatOpenAI -> body+ ThinkingFormatOpenAI ->+ insertTop "reasoning_effort" (String (renderThinkingLevel lvl)) body ThinkingFormatNone -> body ThinkingFormatOpenRouter ->- insertTop "reasoning" (Aeson.object ["effort" .= effort lvl]) body+ insertTop "reasoning" (Aeson.object ["effort" .= compatibleEffort lvl]) body ThinkingFormatDeepseek ->- insertTop "reasoning_effort" (String (effort lvl)) $+ insertTop "reasoning_effort" (String (compatibleEffort lvl)) $ insertTop "thinking" (Aeson.object ["type" .= ("enabled" :: Text)]) body ThinkingFormatTogether ->- insertTop "reasoning_effort" (String (effort lvl)) $+ insertTop "reasoning_effort" (String (compatibleEffort lvl)) $ insertTop "reasoning" (Aeson.object ["enabled" .= True]) body ThinkingFormatZai -> insertTop "enable_thinking" (Bool True) body@@ -208,9 +209,13 @@ key :: Text -> AesonKey.Key key = AesonKey.fromText -effort :: ThinkingLevel -> Text-effort = \case+-- | Common effort vocabulary supported by the non-native+-- OpenAI-compatible request shapes above.+compatibleEffort :: ThinkingLevel -> Text+compatibleEffort = \case ThinkingMinimal -> "low" ThinkingLow -> "low" ThinkingMedium -> "medium" ThinkingHigh -> "high"+ ThinkingXHigh -> "high"+ ThinkingMax -> "high"
test/Main.hs view
@@ -44,6 +44,7 @@ testGroup "Baikai.Provider.OpenAI" [ commandRenderingTest,+ effortRenderingTests, batchCommandRenderingTest, batchSystemPromptTest, stderrFloodTest,@@ -249,6 +250,26 @@ "System instructions:\nBe precise.\n\nUser request:\ninspect the repo" ] )++effortRenderingTests :: TestTree+effortRenderingTests =+ testGroup+ "renders interactive reasoning effort"+ [ testCase name $ do+ let req = interactiveLaunchRequest "prompt" & #effort .~ Just level+ codexInteractiveCommand defaultCodexInteractiveConfig req+ @?= ( "codex",+ ["-c", "model_reasoning_effort=" <> expected, "--", "prompt"]+ )+ | (name, level, expected) <-+ [ ("minimal", ThinkingMinimal, "minimal"),+ ("low", ThinkingLow, "low"),+ ("medium", ThinkingMedium, "medium"),+ ("high", ThinkingHigh, "high"),+ ("xhigh", ThinkingXHigh, "xhigh"),+ ("max", ThinkingMax, "max")+ ]+ ] batchCommandRenderingTest :: TestTree batchCommandRenderingTest =
test/ShapeSpec.hs view
@@ -31,6 +31,8 @@ testGroup "ShapeSpec" [ deepseekShapeTest,+ nativeHigherEffortTests,+ compatibleHigherEffortClampTest, openRouterCacheControlTest, strictModeGateTest, usageStreamingGateTest,@@ -50,6 +52,33 @@ lookupTop "max_tokens" value @?= Just (Number 8192) lookupTop "thinking" value @?= Just (Aeson.object ["type" .= ("enabled" :: Text.Text)])+ lookupTop "reasoning_effort" value @?= Just (String "high")++nativeHigherEffortTests :: TestTree+nativeHigherEffortTests =+ testGroup+ "native OpenAI higher reasoning effort"+ [ testCase name $ do+ value <-+ shapedBody+ Models.openai_gpt_5_6_terra+ (emptyOptions & #thinking .~ Just level)+ emptyContext+ lookupTop "reasoning_effort" value @?= Just (String expected)+ | (name, level, expected) <-+ [ ("xhigh survives SDK staging", ThinkingXHigh, "xhigh"),+ ("max survives SDK staging", ThinkingMax, "max")+ ]+ ]++compatibleHigherEffortClampTest :: TestTree+compatibleHigherEffortClampTest =+ testCase "OpenAI-compatible higher reasoning effort clamps to high" $ do+ value <-+ shapedBody+ Models.deepseek_deepseek_chat+ (emptyOptions & #thinking .~ Just ThinkingMax)+ emptyContext lookupTop "reasoning_effort" value @?= Just (String "high") openRouterCacheControlTest :: TestTree