composable_agents 3.4.2 → 3.5.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: e7f5301018586fe1833b809177d6a65ea6354d15269a23a7cd2576b7a4e32fbf
4
- data.tar.gz: 00ddb291d538fa3e10cc7e1f15988e5b1d61354daaecd80c56e95905f97f09e7
3
+ metadata.gz: 132190ec03c57ad131b72ea3ec35026ec960df4afa592db2de817986ca52f716
4
+ data.tar.gz: dd2f18c46f0b902002dba6dc1e00426723de74bab9311926440122ca810a6426
5
5
  SHA512:
6
- metadata.gz: e60c04ab1c8ee42b3cd1701ee99e99641bef7285316979f726a60155d3a5f907955db3827972cedab6e7065b84e12df7d9817e188476a03e08d44759a577be49
7
- data.tar.gz: 384d21b543720de613ffcc867a8a7ebb77fc983838c19b94a7e14eb2bee8c034f3c04f63c31a1b9de3950d51fcb05aa6b0a0d13e8555d2d154d299b9e91044cf
6
+ metadata.gz: e008ab4e1124e9b2943af61bc31c1d7290f2b2cee575fb6469776e337a141e32a6c2978f156ff5d79cc49e7654663324e7eee91d7521f02ecfb775cac352f8ff
7
+ data.tar.gz: 0f3cda8a0158bf4946a4a4392426dc670d095b6c607999928babb251f9fb6ebdefe12885a62f7d3b8e94566aa42eeaff34749ac6a6f6a744138c4527bd7a9ce1
data/CHANGELOG.md CHANGED
@@ -1,3 +1,21 @@
1
+ # [v3.5.0](https://github.com/Muriel-Salvan/composable_agents/compare/v3.4.3...v3.5.0) (2026-11-06 18:46:37)
2
+
3
+ ## Global changes
4
+ ### Patches
5
+
6
+ * [feat(prompts): pretty-print JSON context and artifacts](https://github.com/Muriel-Salvan/composable_agents/commit/2c32832997d33431a5af0ec931627faa4a87a7a7)
7
+
8
+ ## Changes for prompts
9
+ ### Features
10
+
11
+ * [feat(prompts): pretty-print JSON context and artifacts](https://github.com/Muriel-Salvan/composable_agents/commit/2c32832997d33431a5af0ec931627faa4a87a7a7)
12
+
13
+ # [v3.4.3](https://github.com/Muriel-Salvan/composable_agents/compare/v3.4.2...v3.4.3) (2026-11-05 09:18:36)
14
+
15
+ ### Patches
16
+
17
+ * [fix: normalize Cline session context with recursive JSON-safe conversion](https://github.com/Muriel-Salvan/composable_agents/commit/179334f05dbb758161c11c1d9b8d016c24d46909)
18
+
1
19
  # [v3.4.2](https://github.com/Muriel-Salvan/composable_agents/compare/v3.4.1...v3.4.2) (2026-11-04 16:45:13)
2
20
 
3
21
  ## Global changes
data/TODO.md CHANGED
@@ -1,3 +1,5 @@
1
+ * Add a new Breakable/Interruptable mixin for Cline::Agent with proper methods or config to define conditions to interrupt a run (could be based on timeouts, costs, tokens, infinite loops...).
2
+ * Use a ContextSummarizer agent to shrink the context given in retries.
1
3
  * Add a new mixin for Cline::Agent with proper methods or config to define retries in case of errors, with exponential waits.
2
4
  * Add a new retry mixin for Cline::Agent with proper methods or config to define retries in case of errors and 429 issues to define fallback models in case of errors, with exponential waits (reuse code from the RetriableCline mixin).
3
5
  * Add a way to detect infinite loops in agents and act on it (maybe a mixin looking at prompts/messages).
@@ -122,7 +122,7 @@ module ComposableAgents
122
122
  Here is the conversation from a previous session for context:
123
123
 
124
124
  ```json
125
- #{JSON.dump(@context)}
125
+ #{JSON.pretty_generate(@context)}
126
126
  ```
127
127
 
128
128
  Continue with the task, building on the work from the session above.
@@ -169,32 +169,33 @@ module ComposableAgents
169
169
  # Keep the context in case we need to resume it
170
170
  if cline_cli.session&.messages
171
171
  @context.concat(
172
- cline_cli.session.messages.map.with_index do |message, idx_message|
173
- curated_content = message.content.map.with_index do |content, idx_content|
174
- curated_message = {
175
- type: content.type,
176
- text: (
177
- if idx_message.zero? && idx_content.zero?
178
- # First message is the user prompt, but we don't want to include the context from it
179
- user_prompt
180
- else
181
- content.thinking || content.text
182
- end
183
- ),
184
- input:
185
- if content.input&.question
186
- {
187
- question: content.input.question,
188
- # The options are a Shale collection that JSON can't serialize: keep them as a plain Array
189
- options: content.input.options&.to_a
190
- }.compact
191
- end,
192
- content: content.content
193
- }.compact
194
- curated_message.keys == [:type] ? nil : curated_message
172
+ deep_json_safe(
173
+ cline_cli.session.messages.map.with_index do |message, idx_message|
174
+ curated_content = message.content.map.with_index do |content, idx_content|
175
+ curated_message = {
176
+ type: content.type,
177
+ text: (
178
+ if idx_message.zero? && idx_content.zero?
179
+ # First message is the user prompt, but we don't want to include the context from it
180
+ user_prompt
181
+ else
182
+ content.thinking || content.text
183
+ end
184
+ ),
185
+ input:
186
+ if content.input&.question
187
+ {
188
+ question: content.input.question,
189
+ options: content.input.options
190
+ }.compact
191
+ end,
192
+ content: content.content
193
+ }.compact
194
+ curated_message.keys == [:type] ? nil : curated_message
195
+ end.compact
196
+ curated_content.empty? ? nil : { role: message.role, content: curated_content }
195
197
  end.compact
196
- curated_content.empty? ? nil : { role: message.role, content: curated_content }
197
- end.compact
198
+ )
198
199
  )
199
200
  end
200
201
 
@@ -241,5 +241,24 @@ module ComposableAgents
241
241
  obj
242
242
  end
243
243
  end
244
+
245
+ # Recursively convert any value into a plain, JSON-serializable Ruby object.
246
+ # Some agent states contain Shale objects (e.g. Cline session messages from the cline-rb Rubygem).
247
+ # Shale's to_json accepts no positional argument, while the JSON gem calls to_json with the generator state,
248
+ # so JSON.dump raises ArgumentError on them. Their to_hash (and the to_hash of their collections and maps)
249
+ # returns the equivalent plain structure, so we recurse into it to normalize nested schemas, collections and maps.
250
+ #
251
+ # @param value [Object] Value to normalize
252
+ # @return [Object] Equivalent JSON-serializable value
253
+ def deep_json_safe(value)
254
+ case value
255
+ when Array
256
+ value.map { |element| deep_json_safe(element) }
257
+ when Hash
258
+ value.to_h { |key, element| [key, deep_json_safe(element)] }
259
+ else
260
+ value.respond_to?(:to_hash) ? deep_json_safe(value.to_hash) : value
261
+ end
262
+ end
244
263
  end
245
264
  end
@@ -146,7 +146,7 @@ module ComposableAgents
146
146
  ## `#{art_ref}`
147
147
 
148
148
  ```json input_artifact=#{art_ref}
149
- #{JSON.dump(artifact_content)}
149
+ #{JSON.pretty_generate(artifact_content)}
150
150
  ```
151
151
  EO_ARTIFACT_SECTION
152
152
  end.join("\n\n")
@@ -2,5 +2,5 @@ module ComposableAgents
2
2
  # @!group Public API
3
3
 
4
4
  # Gem version
5
- VERSION = '3.4.2'
5
+ VERSION = '3.5.0'
6
6
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: composable_agents
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.4.2
4
+ version: 3.5.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Muriel Salvan