riffer 0.46.1 → 0.47.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 569f1c5929847037c97cc5552eb38a8609db6a1e67ce99b8135961d50aa7a0b5
4
- data.tar.gz: c8e03583eb04ff2c8922b8d554c10f5a47fb4421b15600905ba21b0d69031aed
3
+ metadata.gz: 63cc9b38354166dc44a162e7fb8cc168cf14e950d8cbbba582fb9710721c25a5
4
+ data.tar.gz: 8a386abc38526d731d7253efbab2c8e2ab345da712762d605f469c5708ec5cca
5
5
  SHA512:
6
- metadata.gz: 6a0380696a959b4c291a5bf52c03eb7a1e06971a60ded5d058311bbdfe9efd99e58bf94506980e2d4b7b0e21257773894d11be4d1a896ea1e7e3ba8e2ce3359e
7
- data.tar.gz: 965f4d1fe6b97f4bd887a1fddd310c7a4cb81b5a0789cf8b91c58c49796abe79f396ec410b6008895275bd16281593a29f53d870e591124ade85b38c62a8fb22
6
+ metadata.gz: 9a36b54ef99b21ea74a8e215c3ba5abb70c2bf949e40bf15056209f9cc4875c62505406568fc5a258508d17735a5d92c360510a5092a4f158733feebd6f64fb4
7
+ data.tar.gz: 69209c501af21331079d0e5374b4b41119619ddd81afa6debeb8e93da3955bb144370cb3c1b506411043de9544f070855c66ef62819d5affadc3d671410b906f
@@ -1,3 +1,3 @@
1
1
  {
2
- ".": "0.46.1"
2
+ ".": "0.47.0"
3
3
  }
data/CHANGELOG.md CHANGED
@@ -5,6 +5,13 @@ All notable changes to this project will be documented in this file.
5
5
  The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
6
6
  and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
7
 
8
+ ## [0.47.0](https://github.com/janeapp/riffer/compare/riffer/v0.46.1...riffer/v0.47.0) (2026-09-11)
9
+
10
+
11
+ ### Features
12
+
13
+ * **bedrock:** moving cachePoint so the conversation tail is cached ([#431](https://github.com/janeapp/riffer/issues/431)) ([4fa44b8](https://github.com/janeapp/riffer/commit/4fa44b817c00642303ac30002c33dd77c6d502ab))
14
+
8
15
  ## [0.46.1](https://github.com/janeapp/riffer/compare/riffer/v0.46.0...riffer/v0.46.1) (2026-09-11)
9
16
 
10
17
 
@@ -94,7 +94,10 @@ model_options additional_model_request_fields: {
94
94
 
95
95
  ### cache_control
96
96
 
97
- Enable prompt caching for models that support it (Claude, Nova). Riffer appends a single Converse `cachePoint` to the stable prefix — after the system array, or after the tools when there is no system prompt — so system instructions and tool definitions are reused across the calls in an agent loop and across conversation turns. The volatile message tail is never cached.
97
+ Enable prompt caching for models that support it (Claude, Nova). Riffer mirrors Anthropic's automatic caching with two Converse `cachePoint` blocks:
98
+
99
+ - A **static** checkpoint at the end of the stable prefix — after the system array, or after the tools when there is no system prompt — so system instructions and tool definitions are reused across every call.
100
+ - A **moving** checkpoint after the last content block of the final message (a user turn or a batch of tool results). Bedrock looks back roughly 20 content blocks from a checkpoint for the longest cached prefix, so the second and later calls in a tool loop, and later turns in a conversation, read the accumulated conversation from cache instead of re-billing it at the full input rate.
98
101
 
99
102
  ```ruby
100
103
  # 5-minute TTL (default)
@@ -104,7 +107,7 @@ model_options cache_control: {type: "ephemeral"}
104
107
  model_options cache_control: {type: "ephemeral", ttl: "1h"}
105
108
  ```
106
109
 
107
- Caching is opt-in: omit `cache_control` and no cachePoint is sent. The breakpoint is only honored once the prefix clears the model's minimum token count; on models that don't support `cachePoint`, the Converse request errors. Verify hits via `response.token_usage.cache_read_tokens`.
110
+ Both checkpoints share the same `ttl`. Caching is opt-in: omit `cache_control` and no cachePoint is sent. A checkpoint is only honored once the content before it clears the model's minimum token count (see the per-model limits in the [AWS prompt caching guide](https://docs.aws.amazon.com/bedrock/latest/userguide/prompt-caching.html)) and is silently ignored below it, so short conversations may see no cache reads at first. On models that don't support `cachePoint`, the Converse request errors. Verify hits via `response.token_usage.cache_read_tokens`, which should grow with each step of an agent loop as the conversation accumulates.
108
111
 
109
112
  ## Example
110
113
 
@@ -129,21 +129,25 @@ class Riffer::Providers::AmazonBedrock < Riffer::Providers::Base
129
129
  params
130
130
  end
131
131
 
132
- # Converse chains +tools -> system -> messages+, so a single +cachePoint+ at
133
- # the end of the system array (or the tools array, when there is no system
134
- # prompt) also caches the preceding sections.
132
+ # Converse treats +tools -> system -> messages+ as one prefix and looks back
133
+ # from a +cachePoint+ for the longest cached run, so the point on the final
134
+ # message reuses the previous step's cache wherever that point sat. Mixed
135
+ # ttls must be ordered 1h before 5m, so both points share one.
135
136
  #--
136
137
  #: (Hash[Symbol, untyped], untyped) -> void
137
138
  def apply_cache_point(params, cache_control)
138
139
  cache_point = { cache_point: build_cache_point(cache_control) }
139
140
  system = params[:system]
140
141
  tools = params.dig(:tool_config, :tools)
142
+ last_message = params[:messages].last
141
143
 
142
144
  if system && !system.empty?
143
145
  system << cache_point
144
146
  elsif tools && !tools.empty?
145
147
  tools << cache_point
146
148
  end
149
+
150
+ last_message[:content] << cache_point if last_message
147
151
  end
148
152
 
149
153
  #--
@@ -2,5 +2,5 @@
2
2
  # rbs_inline: enabled
3
3
 
4
4
  module Riffer
5
- VERSION = "0.46.1" #: String
5
+ VERSION = "0.47.0" #: String
6
6
  end
@@ -45,9 +45,10 @@ class Riffer::Providers::AmazonBedrock < Riffer::Providers::Base
45
45
  # : (Array[Riffer::Messages::Base], String?, Hash[Symbol, untyped]) -> Hash[Symbol, untyped]
46
46
  def build_request_params: (Array[Riffer::Messages::Base], String?, Hash[Symbol, untyped]) -> Hash[Symbol, untyped]
47
47
 
48
- # Converse chains +tools -> system -> messages+, so a single +cachePoint+ at
49
- # the end of the system array (or the tools array, when there is no system
50
- # prompt) also caches the preceding sections.
48
+ # Converse treats +tools -> system -> messages+ as one prefix and looks back
49
+ # from a +cachePoint+ for the longest cached run, so the point on the final
50
+ # message reuses the previous step's cache wherever that point sat. Mixed
51
+ # ttls must be ordered 1h before 5m, so both points share one.
51
52
  # --
52
53
  # : (Hash[Symbol, untyped], untyped) -> void
53
54
  def apply_cache_point: (Hash[Symbol, untyped], untyped) -> void
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: riffer
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.46.1
4
+ version: 0.47.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jake Bottrall