packages feed

shikumi-cache 0.1.2.1 → 0.1.2.2

raw patch · 3 files changed

+77/−7 lines, 3 filesdep ~baikaiPVP ok

version bump matches the API change (PVP)

Dependency ranges changed: baikai

API changes (from Hackage documentation)

Files

CHANGELOG.md view
@@ -2,6 +2,25 @@  ## Unreleased +## 0.1.2.2 — 2026-08-07++### Changed++- Upgraded the `baikai` dependency to the `0.5` series (`>=0.5 && <0.6`).++- `Shikumi.Cache.ResponseJSON`'s orphan `ToJSON`/`FromJSON` for+  `Baikai.Response.Response` are written out by hand instead of derived, and+  they neither write nor read baikai 0.5's new `evidence` field. A cache hit+  replays a stored response without any provider call, so carrying the+  original call's `ModelCallEvidence` would attribute a record of a real+  boundary crossing to a call that never made one. Decoding always yields+  `evidence = Nothing`.++  The encoded keys are otherwise unchanged, so entries written by a pre-0.5+  shikumi still read back and `currentKeyVersion` is untouched. (baikai+  deliberately ships no `FromJSON ModelCallEvidence`, so the derived instance+  could not have been kept regardless.)+ ## 0.1.2.1 - 2026-07-20  ### Changed
shikumi-cache.cabal view
@@ -1,6 +1,6 @@ cabal-version:   3.4 name:            shikumi-cache-version:         0.1.2.1+version:         0.1.2.2 synopsis:        Content-addressed response caching for shikumi (EP-6) category:        AI description:@@ -45,7 +45,7 @@    build-depends:     , aeson-    , baikai         >=0.4      && <0.5+    , baikai         >=0.5      && <0.6     , base           >=4.20     && <5     , blake3     , bytestring@@ -69,7 +69,7 @@   ghc-options:    -threaded -with-rtsopts=-N   build-depends:     , aeson-    , baikai         >=0.4      && <0.5+    , baikai         >=0.5      && <0.6     , base     , bytestring     , containers
src/Shikumi/Cache/ResponseJSON.hs view
@@ -23,9 +23,21 @@ --     repetends; it never affects the typed-output guarantee, which is decoded --     from the assistant __text__ ('AssistantContent', which round-trips --     exactly) — cost is metadata.---   * 'AssistantPayload' / 'Response' use @defaultOptions@ (matching baikai's+--   * 'AssistantPayload' uses @defaultOptions@ (matching baikai's --     @deriving anyclass ToJSON@).+--   * 'Response' is written out by hand with the same keys @defaultOptions@+--     produced, minus @evidence@ — see below. --+-- __'Response' does not cache its 'Baikai.Evidence.ModelCallEvidence'.__ Since+-- baikai 0.5 a 'Response' may carry the evidence record for the call that+-- produced it. That record describes /one/ crossing of the provider boundary; a+-- cache hit is precisely the case where no such crossing happened, so replaying+-- a stored record would attribute another call's evidence to this one — the+-- exact misattribution the evidence vocabulary exists to prevent. The encoder+-- therefore drops the field and the decoder always yields @evidence = Nothing@.+-- Dropping it also keeps the encoding byte-identical to what pre-0.5 shikumi+-- wrote, so cache entries written by an older build still read back.+-- -- This module is the __single home__ for these orphans across the whole -- framework. EP-7's @Shikumi.Trace.ResponseJSON@ re-exports them from here rather -- than defining its own copy, so no module that imports both the cache and the@@ -45,9 +57,11 @@     camelTo2,     defaultOptions,     genericParseJSON,-    genericToJSON,+    object,     withObject,     (.:),+    (.:?),+    (.=),   ) import Data.Aeson.Types (Parser) import Data.Scientific (Scientific)@@ -85,7 +99,44 @@   parseJSON = genericParseJSON defaultOptions  instance ToJSON Response where-  toJSON = genericToJSON defaultOptions+  toJSON+    Response+      { message = m,+        model = mdl,+        api = a,+        provider = p,+        responseId = rid,+        latencyMs = ms,+        errorInfo = e,+        evidence = _+      } =+      object+        [ "message" .= m,+          "model" .= mdl,+          "api" .= a,+          "provider" .= p,+          "responseId" .= rid,+          "latencyMs" .= ms,+          "errorInfo" .= e+        ]  instance FromJSON Response where-  parseJSON = genericParseJSON defaultOptions+  parseJSON = withObject "Response" $ \o -> do+    m <- o .: "message"+    mdl <- o .: "model"+    a <- o .: "api"+    p <- o .: "provider"+    rid <- o .:? "responseId"+    ms <- o .: "latencyMs"+    e <- o .:? "errorInfo"+    pure+      Response+        { message = m,+          model = mdl,+          api = a,+          provider = p,+          responseId = rid,+          latencyMs = ms,+          errorInfo = e,+          evidence = Nothing+        }