packages feed

agentic-jev 0.2.0.2 → 0.2.0.3

raw patch · 5 files changed

+25/−20 lines, 5 filesPVP: major bump suggested

API removals or changes: PVP suggests a major version bump

API changes (from Hackage documentation)

- Agentic.Jev: MissingToken :: JevError
+ Agentic.Jev: MissingKey :: JevError
- Agentic.Jev: Jev :: Text -> Maybe Text -> String -> Int -> Jev
+ Agentic.Jev: Jev :: Text -> Maybe Text -> Text -> Int -> Jev
- Agentic.Jev: [endpoint] :: Jev -> String
+ Agentic.Jev: [endpoint] :: Jev -> Text
- Agentic.Jev: requestBody :: Text -> JudgeRequest -> Value
+ Agentic.Jev: requestBody :: Jev -> JudgeRequest -> Value

Files

CHANGELOG.md view
@@ -1,5 +1,10 @@ # Changelog for agentic-jev +## 0.2.0.3 - 2026-10-06++* `MissingToken` is `MissingKey`, like the other providers.+* `requestBody` takes the `Jev` settings, like the other providers.+ ## 0.2.0.2 - 2026-10-01  * No changes; released alongside agentic 0.2.0.2.
agentic-jev.cabal view
@@ -1,6 +1,6 @@ cabal-version:      3.0 name:               agentic-jev-version:            0.2.0.2+version:            0.2.0.3 synopsis:           Jev (TypeSafe) as the System One provider for agentic description:   Answers agentic's judgements (yes/no, choice and score questions) with Jev, TypeSafe's System One model, which returns calibrated probabilities.
src/Agentic/Jev.hs view
@@ -36,7 +36,7 @@   { model :: Text   , key :: Maybe Text     -- ^ Defaults to the @JEV_TOKEN@ environment variable.-  , endpoint :: String+  , endpoint :: Text   , timeout :: Int     -- ^ Seconds.   }@@ -57,7 +57,7 @@  -- | What can go wrong talking to Jev. Thrown in IO. data JevError-  = MissingToken+  = MissingKey   | HttpError Int Text     -- ^ Jev answered with a non-200 status, and this body.   | UnexpectedResponse Text@@ -65,16 +65,16 @@  instance Exception JevError where   displayException = \case-    MissingToken -> "Jev: no token. Set JEV_TOKEN, or use (jev & key ...)."+    MissingKey -> "Jev: no key. Set JEV_TOKEN, or use (jev & key ...)."     HttpError status body -> "Jev rejected the request (HTTP " <> show status <> "): " <> T.unpack body     UnexpectedResponse problem -> "Jev sent a response agentic can't read: " <> T.unpack problem  instance ProvidesSystemOne Jev where   toSystemOne cfg = do     token <- maybe (fmap T.pack <$> lookupEnv "JEV_TOKEN") (pure . Just) cfg.key-    token' <- maybe (throwIO MissingToken) pure token+    token' <- maybe (throwIO MissingKey) pure token     manager <- newTlsManager-    base <- Http.parseRequest cfg.endpoint+    base <- Http.parseRequest (T.unpack cfg.endpoint)     pure $ SystemOne $ \request -> do       let http =             base@@ -83,7 +83,7 @@                   [ ("Authorization", "Bearer " <> T.encodeUtf8 token')                   , ("Content-Type", "application/json")                   ]-              , Http.requestBody = Http.RequestBodyBS (T.encodeUtf8 (A.renderJson (requestBody cfg.model request)))+              , Http.requestBody = Http.RequestBodyBS (T.encodeUtf8 (A.renderJson (requestBody cfg request)))               , Http.responseTimeout = Http.responseTimeoutMicro (cfg.timeout * 1000000)               }       response <- Http.httpLbs http manager@@ -95,13 +95,13 @@           Left problem -> throwIO (UnexpectedResponse (T.pack problem))           Right value -> either (throwIO . UnexpectedResponse) pure (decodeResponse request value) --- | The request body: the state, and each question under an id (@q0@, @q1@, …).+-- | The request body: the input (Jev's @state@), and each question under an id (@q0@, @q1@, …). -- It's the core's 'A.Value' so that options keep their order.-requestBody :: Text -> JudgeRequest -> A.Value-requestBody name request =+requestBody :: Jev -> JudgeRequest -> A.Value+requestBody cfg request =   A.Object-    [ ("model", A.String name)-    , ("state", requestState request)+    [ ("model", A.String cfg.model)+    , ("state", requestInput request)     , ("questions", A.Object [(qid, question q) | (qid, q) <- ided (requestQuestions request)])     ]   where@@ -128,19 +128,19 @@       answers <- response .: "answers"       traverse (\(qid, q) -> answers .: Key.fromText qid >>= answer q) (ided (requestQuestions request))     answer q = J.withObject "answer" $ \a -> case q of-      AskYesNo _ -> YesNoAnswer . fromBasisPoints <$> a .: "noul"+      AskYesNo _ -> YesNoAnswer . toProbability <$> a .: "noul"       AskChoice _ opts -> do         ps <- a .: "probabilities"         ChoiceAnswer           <$> a .: "choice"-          <*> traverse (\(l, _) -> (l,) . fromBasisPoints <$> ps .: Key.fromText l) opts-          <*> (fromBasisPoints <$> a .: "confidence")+          <*> traverse (\(l, _) -> (l,) . toProbability <$> ps .: Key.fromText l) opts+          <*> (toProbability <$> a .: "confidence")       AskScore _ levels -> do         ps <- a .: "probabilities"         ScoreAnswer           <$> a .: "score"-          <*> traverse (\i -> (i,) . fromBasisPoints <$> ps .: Key.fromText (T.pack (show i))) [0 .. length levels - 1]-          <*> (fromBasisPoints <$> a .: "confidence")+          <*> traverse (\i -> (i,) . toProbability <$> ps .: Key.fromText (T.pack (show i))) [0 .. length levels - 1]+          <*> (toProbability <$> a .: "confidence")  ided :: [a] -> [(Text, a)] ided = zip ["q" <> T.pack (show n) | n <- [0 :: Int ..]]
test-live/Live.hs view
@@ -17,7 +17,7 @@  instance Options Groan where   options =-    described+    documentedOptions       "How much the audience groans"       [ option Mild "A polite smile; most people didn't notice"       , option Solid "An audible groan from most of the room"
test/Spec.hs view
@@ -13,7 +13,7 @@   deriving (Generic, Show, Eq)  instance Options Groan where-  options = described "" [option Mild "A polite smile", option Solid "An audible groan", option Unbearable "People leave"]+  options = documentedOptions "" [option Mild "A polite smile", option Solid "An audible groan", option Unbearable "People leave"]  request :: JudgeRequest request =@@ -25,7 +25,7 @@ main :: IO () main = hspec $ Test.Hspec.describe "Agentic.Jev" $ do   it "builds Jev's request body" $-    toAeson (requestBody "jev-latest" request)+    toAeson (requestBody jev request)       `shouldBe` fromJust         ( J.decode             "{\"model\":\"jev-latest\",\