ruby-mana 0.4.0 → 0.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: c5998b08056a2657d73e7ab5382fd9ad3a96a53c9cbaa3268a98f6798c7290da
4
- data.tar.gz: 82326fc68f9c15694f70dcbea19b43b321674f766497864c824ee574023a7f1c
3
+ metadata.gz: 04d7095024d30500930422b72e86fcdb1a27b1fa9a9f62ca70c9c124c2ceab77
4
+ data.tar.gz: 6e264f8292e908d45776481aa6af33bed5eb7d9113874d13e72f3a3cde513107
5
5
  SHA512:
6
- metadata.gz: a612ba5f45d2bd5abf09fd68e7225945e5d3defa70f0bd5298e55215010bfe71dd1a7f53adf415e126fe3a97c654fa209812e8db8b3720d8258355054767eb7d
7
- data.tar.gz: 3649cc64a401d6d8e92b16ae8cc05999b9a6e5813a16d25a62c7661573827e3086b30e49f9d62e0c57c48a2ea6d081307a053d64d53e5de4d565db607dc76574
6
+ metadata.gz: 470e54537747878bbe07c6825a12bf515a2909af872ee4908e0eb07a0e58b31187dacadb6b20d988782a8f9a2bfaf12c4523ae09c149dc764ad90c2b8a420871
7
+ data.tar.gz: 1c322b45e74e8fa67aab109c10a5a7cac2d6546d1de61912157192e9f15330b8c2520bd5e90b4c70b942d36b7de4ecabfc165c2774be4b8489936e68e14614a0
data/CHANGELOG.md CHANGED
@@ -1,6 +1,46 @@
1
1
  # Changelog
2
2
 
3
- ## [0.1.0] - Unreleased
3
+ ## [0.5.0] - 2026-02-22
4
+
5
+ ### Added
6
+ - **Polyglot engine architecture** — run Ruby, JavaScript, and Python code side by side
7
+ - JavaScript engine via `mini_racer` with automatic variable bridging
8
+ - Python engine via `pycall` with automatic variable bridging
9
+ - Bidirectional Python ↔ Ruby calling through pycall bridge
10
+ - Engine interface abstraction (`Mana::Engines::Base`)
11
+ - Language auto-detection for polyglot dispatch
12
+
13
+ ### Changed
14
+ - Refactored LLM logic into `Engines::LLM`, extracted from monolithic core
15
+
16
+ ### Fixed
17
+ - Polyglot engine bug fixes (CodeRabbit review feedback)
18
+
19
+ ## [0.4.0] - 2026-02-22
20
+
21
+ - Multi-LLM backend — Anthropic + OpenAI-compatible APIs
22
+ - Test mode — `Mana.mock` + `mock_prompt` for stubbing LLM responses
23
+
24
+ ## [0.3.1] - 2026-02-21
25
+
26
+ - Nested prompts — LLM calling LLM
27
+ - Lambda `call_func` support
28
+ - Expanded test coverage
29
+
30
+ ## [0.3.0] - 2026-02-21
31
+
32
+ - Automatic memory — context sharing across LLM calls
33
+ - Incognito mode
34
+ - Persistent long-term memory
35
+ - `Mana.session` — shared conversation context across prompts
36
+
37
+ ## [0.2.0] - 2026-02-20
38
+
39
+ - Custom effect handlers — user-defined LLM tools
40
+ - `mana def` — LLM-compiled methods with file caching
41
+ - Auto-discover functions via Prism introspection
42
+
43
+ ## [0.1.0] - 2026-02-19
4
44
 
5
45
  - Initial release
6
46
  - `~"..."` syntax for embedding LLM prompts in Ruby
data/README.md CHANGED
@@ -254,6 +254,74 @@ Mana.incognito do
254
254
  end
255
255
  ```
256
256
 
257
+ ### Polyglot — Cross-Language Interop
258
+
259
+ `~"..."` is a universal operator. It detects whether the code is JavaScript, Python, Ruby, or natural language, and routes to the appropriate engine. Variables bridge automatically.
260
+
261
+ #### JavaScript
262
+
263
+ ```ruby
264
+ require "mana"
265
+
266
+ data = [1, 2, 3, 4, 5]
267
+
268
+ # JavaScript — auto-detected from syntax
269
+ ~"const evens = data.filter(n => n % 2 === 0)"
270
+ puts evens # => [2, 4]
271
+
272
+ # Multi-line with heredoc
273
+ ~<<~JS
274
+ const sum = evens.reduce((a, b) => a + b, 0)
275
+ const avg = sum / evens.length
276
+ JS
277
+ puts avg # => 3.0
278
+ ```
279
+
280
+ #### Python
281
+
282
+ ```ruby
283
+ # Python — auto-detected
284
+ ~"evens = [n for n in data if n % 2 == 0]"
285
+ puts evens # => [2, 4]
286
+
287
+ # Multi-line
288
+ ~<<~PY
289
+ import statistics
290
+ mean = statistics.mean(data)
291
+ stdev = statistics.stdev(data)
292
+ PY
293
+ puts mean # => 3.0
294
+ ```
295
+
296
+ #### Natural language (LLM) — existing behavior
297
+
298
+ ```ruby
299
+ ~"analyze <data> and find outliers, store in <result>"
300
+ puts result
301
+ ```
302
+
303
+ #### How detection works
304
+
305
+ - Auto-detects from code syntax (token patterns)
306
+ - Context-aware: consecutive `~"..."` calls tend to stay in the same language
307
+ - Override with `Mana.engine = :javascript` or `Mana.with(:python) { ... }`
308
+ - Detection rules are defined in `data/lang-rules.yml` — transparent, no black box
309
+
310
+ #### Variable bridging
311
+
312
+ - Simple types (numbers, strings, booleans, nil, arrays, hashes) are copied
313
+ - Each engine maintains a persistent context (V8 for JS, Python interpreter for Python)
314
+ - Variables created in one `~"..."` call persist for the next call in the same engine
315
+
316
+ #### Setup
317
+
318
+ ```ruby
319
+ # Gemfile
320
+ gem "mana"
321
+ gem "mini_racer" # for JavaScript support (optional)
322
+ gem "pycall" # for Python support (optional)
323
+ ```
324
+
257
325
  ### Testing
258
326
 
259
327
  Use `Mana.mock` to test code that uses `~"..."` without calling any API:
@@ -0,0 +1,196 @@
1
+ version: 1
2
+ languages:
3
+ javascript:
4
+ strong:
5
+ - "const "
6
+ - "let "
7
+ - "=> "
8
+ - "=== "
9
+ - "!== "
10
+ - "console.log"
11
+ - "console.error"
12
+ - ".filter("
13
+ - ".map("
14
+ - ".reduce("
15
+ - ".forEach("
16
+ - ".indexOf("
17
+ - ".push("
18
+ - "function "
19
+ - "async "
20
+ - "await "
21
+ - "require("
22
+ - "module.exports"
23
+ - "export "
24
+ - "import "
25
+ - "new Promise"
26
+ - "document."
27
+ - "window."
28
+ - "JSON.parse"
29
+ - "JSON.stringify"
30
+ - "typeof "
31
+ - "undefined"
32
+ - "null;"
33
+ weak:
34
+ - "var "
35
+ - "return "
36
+ - "true"
37
+ - "false"
38
+ - "null"
39
+ - "this."
40
+ anti:
41
+ - "let me"
42
+ - "let us"
43
+ - "let's"
44
+ - "const ant"
45
+ - "import ant"
46
+ - "import this"
47
+ patterns:
48
+ - "\\bfunction\\s+\\w+\\s*\\("
49
+ - "\\(\\s*\\w+\\s*\\)\\s*=>"
50
+ - "\\bclass\\s+\\w+\\s*\\{"
51
+
52
+ python:
53
+ strong:
54
+ - "elif "
55
+ - "print("
56
+ - "__init__"
57
+ - "__name__"
58
+ - "self."
59
+ - "import numpy"
60
+ - "import pandas"
61
+ - "lambda "
62
+ - "except "
63
+ - "finally:"
64
+ - "nonlocal "
65
+ weak:
66
+ - "def "
67
+ - "from "
68
+ - "yield "
69
+ - "raise "
70
+ - "assert "
71
+ - "global "
72
+ - "import "
73
+ - "return "
74
+ - "class "
75
+ - "for "
76
+ - "while "
77
+ - "if "
78
+ - "is not"
79
+ - "not in"
80
+ - "pass"
81
+ anti:
82
+ - "import this"
83
+ - "import that"
84
+ - "from here"
85
+ - "from there"
86
+ - "for example"
87
+ - "for instance"
88
+ - "while I"
89
+ - "while we"
90
+ - "if you"
91
+ - "if we"
92
+ - "with you"
93
+ - "with the"
94
+ - "with a "
95
+ - "with my"
96
+ - "and the"
97
+ - "and I"
98
+ - "and we"
99
+ - "or the"
100
+ - "or a "
101
+ - "or I"
102
+ - "or False"
103
+ - "True or"
104
+ - "as a "
105
+ - "as the"
106
+ - "as I"
107
+ - "pass the"
108
+ - "pass it"
109
+ - "pass on"
110
+ patterns:
111
+ - "\\[.+\\bfor\\b.+\\bin\\b.+\\]"
112
+ - "\\bdef\\s+\\w+\\s*\\("
113
+ - "\\bclass\\s+\\w+\\s*[:(]"
114
+ - "^\\s{4}"
115
+
116
+ ruby:
117
+ strong:
118
+ - "puts "
119
+ - "require "
120
+ - "require_relative"
121
+ - "attr_accessor"
122
+ - "attr_reader"
123
+ - "attr_writer"
124
+ - ".each "
125
+ - ".map "
126
+ - ".select "
127
+ - ".reject "
128
+ - "do |"
129
+ - "def "
130
+ - "module "
131
+ - "rescue "
132
+ - "ensure "
133
+ - "unless "
134
+ - "until "
135
+ - "elsif "
136
+ - "nil"
137
+ - "p "
138
+ - "pp "
139
+ - "Proc.new"
140
+ - "lambda {"
141
+ - "-> {"
142
+ weak:
143
+ - "end"
144
+ - "begin"
145
+ - "class "
146
+ - "return "
147
+ - "if "
148
+ - "for "
149
+ - "while "
150
+ anti:
151
+ - "the end"
152
+ - "in the end"
153
+ - "at the end"
154
+ - "begin with"
155
+ - "begin to"
156
+ patterns:
157
+ - "\\bdo\\s*\\|\\w+\\|"
158
+ - "\\bdef\\s+\\w+[?!]?"
159
+ - "\\bend\\b"
160
+
161
+ natural_language:
162
+ strong:
163
+ - "please "
164
+ - "analyze "
165
+ - "summarize "
166
+ - "translate "
167
+ - "explain "
168
+ - "find "
169
+ - "calculate "
170
+ - "generate "
171
+ - "create "
172
+ - "write "
173
+ - "describe "
174
+ - "compare "
175
+ - "store in <"
176
+ - "save in <"
177
+ - "put in <"
178
+ - ", store "
179
+ - ", save "
180
+ weak:
181
+ - "the "
182
+ - "a "
183
+ - "an "
184
+ - "is "
185
+ - "are "
186
+ - "was "
187
+ - "were "
188
+ - "what "
189
+ - "how "
190
+ - "why "
191
+ - "when "
192
+ - "where "
193
+ - "which "
194
+ anti: []
195
+ patterns:
196
+ - "<\\w+>"
data/lib/mana/compiler.rb CHANGED
@@ -74,7 +74,7 @@ module Mana
74
74
  "Return ONLY the complete method definition (def...end), no explanation. " \
75
75
  "Store the code as a string in <code>"
76
76
 
77
- Mana::Engine.run(engine_prompt, b)
77
+ Mana::Engines::LLM.new(b).execute(engine_prompt)
78
78
  code
79
79
  end
80
80