ruby-mana 0.3.0 → 0.3.1

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: ddacfb41b0e2ca07887ffd1c683e211f90529901a4a401393c1c1da91f5da46c
4
- data.tar.gz: 33db80124c57c45499b0a8ae392463782d6e3c6f221853e9d1353ac7f64838af
3
+ metadata.gz: 66fae9938dbde50412ea78e15f01724b7ce584395e0f3d0e0d591041e183fa97
4
+ data.tar.gz: ecb38c4f7a943724caed5c6d01da58ed7bf93b210fb5e3bd0bcb710ed6b938e4
5
5
  SHA512:
6
- metadata.gz: 2c604e080b7a6d4cf04d54d4782d7c36d9789d76f7e485728c1eb1869757ae320d688a8f222c00d9591116e300fec2f7272d77f04b1d9c402edef714ea628b24
7
- data.tar.gz: 2ac2008b69a995bf5d1c4a098d25e3cb89b02b6a83e48c15014a7ba1268efecb3f84ca756a4efd3d53a200b6e160d0c79c38f6571eb581895dac6a9764e343e7
6
+ metadata.gz: d207d98300ee79db472a0d07a2127ccb5fe0e9f6101b9187c4e83b8add90bcdd88cb4b3de3daff3d4eaa1344d7eab747f85a0cb12edf37648683450d53777aa6
7
+ data.tar.gz: e70a43679205f5e8768a415fe020862c175b17f00eff0f479b5f9c5aaf053d62493f98cd09b7eaa3817f663e6d66d72f166bb6aef386de77b324154adee905cb
data/README.md CHANGED
@@ -217,6 +217,23 @@ Mana.incognito do
217
217
  end
218
218
  ```
219
219
 
220
+ ### Nested prompts
221
+
222
+ Functions called by LLM can themselves contain `~"..."` prompts:
223
+
224
+ ```ruby
225
+ lint = ->(code) { ~"check #{code} for style issues, store in <issues>" }
226
+ # Equivalent to:
227
+ # def lint(code)
228
+ # ~"check #{code} for style issues, store in <issues>"
229
+ # issues
230
+ # end
231
+
232
+ ~"review <codebase>, call lint for each file, store report in <report>"
233
+ ```
234
+
235
+ Each nested call gets its own conversation context. The outer LLM only sees the function's return value, keeping its context clean.
236
+
220
237
  ### LLM-compiled methods
221
238
 
222
239
  `mana def` lets LLM generate a method implementation on first call. The generated code is cached as a real `.rb` file — subsequent calls are pure Ruby with zero API overhead.
data/lib/mana/engine.rb CHANGED
@@ -120,6 +120,20 @@ module Mana
120
120
  end
121
121
 
122
122
  def execute
123
+ Thread.current[:mana_depth] ||= 0
124
+ Thread.current[:mana_depth] += 1
125
+ nested = Thread.current[:mana_depth] > 1
126
+
127
+ # Nested calls get fresh short-term memory but share long-term
128
+ if nested && !@incognito
129
+ outer_memory = Thread.current[:mana_memory]
130
+ inner_memory = Mana::Memory.new
131
+ long_term = outer_memory&.long_term || []
132
+ inner_memory.instance_variable_set(:@long_term, long_term)
133
+ inner_memory.instance_variable_set(:@next_id, (long_term.map { |m| m[:id] }.max || 0) + 1)
134
+ Thread.current[:mana_memory] = inner_memory
135
+ end
136
+
123
137
  context = build_context(@prompt)
124
138
  system_prompt = build_system_prompt(context)
125
139
 
@@ -162,10 +176,15 @@ module Mana
162
176
  messages << { role: "assistant", content: [{ type: "text", text: "Done: #{done_result}" }] }
163
177
  end
164
178
 
165
- # Schedule compaction if needed (runs in background)
166
- memory&.schedule_compaction
179
+ # Schedule compaction if needed (runs in background, skip for nested)
180
+ memory&.schedule_compaction unless nested
167
181
 
168
182
  done_result
183
+ ensure
184
+ if nested && !@incognito
185
+ Thread.current[:mana_memory] = outer_memory
186
+ end
187
+ Thread.current[:mana_depth] -= 1
169
188
  end
170
189
 
171
190
  private
@@ -298,7 +317,15 @@ module Mana
298
317
  func = input["name"]
299
318
  validate_name!(func)
300
319
  args = input["args"] || []
301
- result = @binding.receiver.method(func.to_sym).call(*args)
320
+ # Try method first, then local variable (supports lambdas/procs)
321
+ callable = if @binding.receiver.respond_to?(func.to_sym, true)
322
+ @binding.receiver.method(func.to_sym)
323
+ elsif @binding.local_variables.include?(func.to_sym)
324
+ @binding.local_variable_get(func.to_sym)
325
+ else
326
+ @binding.receiver.method(func.to_sym) # raise NameError
327
+ end
328
+ result = callable.call(*args)
302
329
  serialize_value(result)
303
330
 
304
331
  when "remember"
@@ -5,13 +5,6 @@ require "binding_of_caller"
5
5
  class String
6
6
  # ~"natural language prompt" → execute via Mana engine
7
7
  def ~@
8
- return self if Thread.current[:mana_running]
9
-
10
- Thread.current[:mana_running] = true
11
- begin
12
- Mana::Engine.run(self, binding.of_caller(1))
13
- ensure
14
- Thread.current[:mana_running] = false
15
- end
8
+ Mana::Engine.run(self, binding.of_caller(1))
16
9
  end
17
10
  end
data/lib/mana/version.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Mana
4
- VERSION = "0.3.0"
4
+ VERSION = "0.3.1"
5
5
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ruby-mana
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.0
4
+ version: 0.3.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Carl