shikumi-cache 0.2.1.0 → 0.2.1.1
raw patch · 3 files changed
+52/−5 lines, 3 filesdep ~shikumidep ~shikumi-cachePVP ok
version bump matches the API change (PVP)
Dependency ranges changed: shikumi, shikumi-cache
API changes (from Hackage documentation)
Files
- CHANGELOG.md +9/−0
- shikumi-cache.cabal +4/−4
- test/Main.hs +39/−1
CHANGELOG.md view
@@ -2,6 +2,15 @@ ## Unreleased +## 0.2.1.1 — 2026-11-03++### Changed++- Add decision cache coverage for evidence removal, evidence-request bypass,+ structured response serialization, and continued stream cache bypass.+- Require `shikumi ^>=0.5.1.0` for the accompanying structured stream test helpers.+ Production cache behavior is unchanged.+ ## 0.2.1.0 — 2026-11-02 ### Changed
shikumi-cache.cabal view
@@ -1,6 +1,6 @@ cabal-version: 3.4 name: shikumi-cache-version: 0.2.1.0+version: 0.2.1.1 synopsis: Content-addressed response caching for shikumi (EP-6) category: AI description:@@ -61,7 +61,7 @@ generic-lens >=2.2 && <2.4, lens ^>=5.3, scientific >=0.3 && <0.4,- shikumi ^>=0.5.0.0,+ shikumi ^>=0.5.1.0, stm >=2.5 && <2.6, text ^>=2.1, time >=1.12 && <1.17,@@ -89,8 +89,8 @@ generic-lens, lens, process,- shikumi ^>=0.5.0.0,- shikumi-cache ^>=0.2.1.0,+ shikumi ^>=0.5.1.0,+ shikumi-cache ^>=0.2.1.1, shikumi-testing, stm, tasty,
test/Main.hs view
@@ -72,11 +72,13 @@ import Shikumi.Effect.Time (runTime) import Shikumi.Error (ShikumiError (..)) import Shikumi.LLM (LLM (..), complete)+import Shikumi.LLM qualified as L import Shikumi.LLM.Continuation (contextIdentity, requestOrigin, stampContinuation) import Shikumi.LLM.Defaults import Shikumi.Program qualified as P import Shikumi.Routing (routeLLM, runRouting) import Shikumi.Schema (field)+import Shikumi.Stream (atomicEventsFromResponse) import Shikumi.Testing.DecisionFixtures import Shikumi.Testing.Response (evidenceJSONResponse, evidenceMarkerResponse) import Shikumi.Testing.StubLLM (captureLLMRequests)@@ -149,7 +151,43 @@ defaultMain $ testGroup "shikumi-cache"- [ testCase "Decision settings reuse evidence with identical cache keys on all backends" $ do+ [ testCase "decision cache hits clear evidence while evidence requests and streams dispatch" $ do+ cache <- newMemoryCache+ calls <- newIORef 0+ let ev =+ E.baseEvidence+ (E.evidenceRequest "historical")+ "historical-call"+ (E.EndpointIdentity "fixture" "custom" E.TransportHttpApi Nothing "fixture" Nothing)+ "model"+ E.noThinkingRequested+ someTime+ someTime+ E.CallSucceeded+ "digest"+ "config"+ response = systemOneResponse [("flag", FieldNoul (NoulEvidence 0.8))] & #evidence .~ Just ev+ interpreter = interpret $ \_ -> \case+ Complete {} -> liftIO (modifyIORef' calls (+ 1)) >> pure response+ Stream {} -> liftIO (modifyIORef' calls (+ 1)) >> maybe (error "fixture") pure (atomicEventsFromResponse response)+ requested = fixOpts & #evidence .~ Just (E.evidenceRequest "new")+ result <- runEff . runConcurrent . runTime . runErrorNoCallStack @ShikumiError . interpreter . runCacheMemory cache . cachedLLM $ do+ first <- complete fixModel fixCtx fixOpts+ hit <- complete fixModel fixCtx fixOpts+ fresh <- complete fixModel fixCtx requested+ events <- L.stream fixModel fixCtx fixOpts+ pure (first, hit, fresh, events)+ case result of+ Right (first, hit, fresh, events) -> do+ first ^. #evidence @?= Just ev+ hit ^. #evidence @?= Nothing+ hit ^. #message . #content @?= first ^. #message . #content+ fresh ^. #evidence @?= Just ev+ assertBool "stream still dispatched" (not (null events))+ eitherDecode (encode first) @?= Right (first & #evidence .~ Nothing)+ Left err -> assertFailure (show err)+ readIORef calls >>= (@?= 3),+ testCase "Decision settings reuse evidence with identical cache keys on all backends" $ do let fields = [("urgent", FieldNoul (NoulEvidence 0.6)), ("severity", FieldScore (ScoreEvidence (V.fromList [0.1, 0.3, 0.6]) (Just 0.8))), ("category", FieldChoice (ChoiceEvidence (Map.fromList [("billing", 0.2), ("technical", 0.8)]) (Just 0.8)))] payload = \case FieldNoul e -> toJSON e; FieldChoice e -> toJSON e; FieldScore e -> toJSON e values = [(k, payload e) | (k, e) <- fields]