elelem 0.4.0 → 0.4.2
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 +4 -4
- data/CHANGELOG.md +22 -0
- data/README.md +2 -2
- data/Rakefile +11 -0
- data/lib/elelem/agent.rb +10 -16
- data/lib/elelem/application.rb +14 -1
- data/lib/elelem/conversation.rb +7 -7
- data/lib/elelem/system_prompt.erb +13 -3
- data/lib/elelem/tool.rb +4 -3
- data/lib/elelem/toolbox.rb +2 -2
- data/lib/elelem/version.rb +1 -1
- metadata +5 -5
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 7c9f3ee321bf585693ae2be5186a3b84f0122f282bcd8cb6d320b92931eb0d13
|
|
4
|
+
data.tar.gz: f9200f6646a49666394493f46a99ec5ebb157d415e35208a8cdb405736c822c1
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: b62630ba5787d5b7daa55113c01012ade1075f4d9618b43c6a4ce46643b4a29ce3d380c864070f6aa43e26732ae6e20b07f4ce7eb7b4b251b90fd83f5ff5c781
|
|
7
|
+
data.tar.gz: 48929614d89e694d9d153baa195276042d586a537f1197c588156cf8d192afd4b6b134bad5bd30c836a05358ff26607ae6b7531f5f71e33f9e0291f0d5331e2d
|
data/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,26 @@
|
|
|
1
1
|
## [Unreleased]
|
|
2
2
|
|
|
3
|
+
## [0.4.2] - 2025-12-01
|
|
4
|
+
|
|
5
|
+
### Changed
|
|
6
|
+
- Renamed `exec` tool to `bash` for clarity
|
|
7
|
+
- Improved system prompt with iterative refinements
|
|
8
|
+
- Added environment context variables to system prompt
|
|
9
|
+
|
|
10
|
+
## [0.4.1] - 2025-11-26
|
|
11
|
+
|
|
12
|
+
### Added
|
|
13
|
+
- `elelem files` subcommand: generates Claude‑compatible XML file listings.
|
|
14
|
+
- Rake task `files:prompt` to output a ready‑to‑copy list of files for prompts.
|
|
15
|
+
|
|
16
|
+
### Changed
|
|
17
|
+
- Refactor tool‑call formatting to a more compact JSON payload for better LLM parsing.
|
|
18
|
+
- Updated CI and documentation to use GitHub instead of previous hosting.
|
|
19
|
+
- Runtime validation of command‑line parameters against a JSON schema.
|
|
20
|
+
|
|
21
|
+
### Fixed
|
|
22
|
+
- Minor documentation and CI workflow adjustments.
|
|
23
|
+
|
|
3
24
|
## [0.4.0] - 2025-11-10
|
|
4
25
|
|
|
5
26
|
### Added
|
|
@@ -116,3 +137,4 @@
|
|
|
116
137
|
## [0.1.0] - 2025-08-08
|
|
117
138
|
|
|
118
139
|
- Initial release
|
|
140
|
+
|
data/README.md
CHANGED
|
@@ -125,13 +125,13 @@ seven tools, each represented by a JSON schema that the LLM can call.
|
|
|
125
125
|
|
|
126
126
|
| Tool | Purpose | Parameters |
|
|
127
127
|
| ---- | ------- | ---------- |
|
|
128
|
+
| `bash` | Run shell commands | `cmd`, `args`, `env`, `cwd`, `stdin` |
|
|
128
129
|
| `eval` | Dynamically create new tools | `code` |
|
|
129
130
|
| `grep` | Search Git‑tracked files | `query` |
|
|
130
131
|
| `list` | List tracked files | `path` (optional) |
|
|
132
|
+
| `patch` | Apply a unified diff via `git apply` | `diff` |
|
|
131
133
|
| `read` | Read file contents | `path` |
|
|
132
134
|
| `write` | Overwrite a file | `path`, `content` |
|
|
133
|
-
| `patch` | Apply a unified diff via `git apply` | `diff` |
|
|
134
|
-
| `execute` | Run shell commands | `cmd`, `args`, `env`, `cwd`, `stdin` |
|
|
135
135
|
|
|
136
136
|
## Tool Definition
|
|
137
137
|
|
data/Rakefile
CHANGED
|
@@ -5,4 +5,15 @@ require "rspec/core/rake_task"
|
|
|
5
5
|
|
|
6
6
|
RSpec::Core::RakeTask.new(:spec)
|
|
7
7
|
|
|
8
|
+
task :files do
|
|
9
|
+
IO.popen(%w[git ls-files], chdir: __dir__, err: IO::NULL) do |ls|
|
|
10
|
+
ls.readlines.each do |f|
|
|
11
|
+
next if f.start_with?(*%w[bin/ spec/ pkg/ .git .rspec Gemfile Rakefile])
|
|
12
|
+
next if f.strip.end_with?(*%w[.toml .txt .md])
|
|
13
|
+
|
|
14
|
+
puts f
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
|
|
8
19
|
task default: %i[spec]
|
data/lib/elelem/agent.rb
CHANGED
|
@@ -65,20 +65,13 @@ module Elelem
|
|
|
65
65
|
HELP
|
|
66
66
|
end
|
|
67
67
|
|
|
68
|
-
def
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
when "list" then "list(#{args["path"] || "."})"
|
|
76
|
-
when "patch" then "patch(#{args["diff"]&.lines&.count || 0} lines)"
|
|
77
|
-
when "read" then "read(#{args["path"]})"
|
|
78
|
-
when "write" then "write(#{args["path"]})"
|
|
79
|
-
else
|
|
80
|
-
"#{name}(#{args.to_s[0...50]})"
|
|
81
|
-
end
|
|
68
|
+
def format_tool_call_result(result)
|
|
69
|
+
return if result.nil?
|
|
70
|
+
return result["stdout"] if result["stdout"]
|
|
71
|
+
return result["stderr"] if result["stderr"]
|
|
72
|
+
return result[:error] if result[:error]
|
|
73
|
+
|
|
74
|
+
""
|
|
82
75
|
end
|
|
83
76
|
|
|
84
77
|
def execute_turn(messages, tools:)
|
|
@@ -88,7 +81,7 @@ module Elelem
|
|
|
88
81
|
content = ""
|
|
89
82
|
tool_calls = []
|
|
90
83
|
|
|
91
|
-
print "Thinking..."
|
|
84
|
+
print "Assistant> Thinking..."
|
|
92
85
|
client.chat(messages + turn_context, tools) do |chunk|
|
|
93
86
|
msg = chunk["message"]
|
|
94
87
|
if msg
|
|
@@ -110,8 +103,9 @@ module Elelem
|
|
|
110
103
|
name = call.dig("function", "name")
|
|
111
104
|
args = call.dig("function", "arguments")
|
|
112
105
|
|
|
113
|
-
puts "Tool> #{
|
|
106
|
+
puts "Tool> #{name}(#{args})"
|
|
114
107
|
result = toolbox.run_tool(name, args)
|
|
108
|
+
puts format_tool_call_result(result)
|
|
115
109
|
turn_context << { role: "tool", content: JSON.dump(result) }
|
|
116
110
|
end
|
|
117
111
|
|
data/lib/elelem/application.rb
CHANGED
|
@@ -13,7 +13,6 @@ module Elelem
|
|
|
13
13
|
type: :string,
|
|
14
14
|
desc: "Ollama model",
|
|
15
15
|
default: ENV.fetch("OLLAMA_MODEL", "gpt-oss")
|
|
16
|
-
|
|
17
16
|
def chat(*)
|
|
18
17
|
client = Net::Llm::Ollama.new(
|
|
19
18
|
host: options[:host],
|
|
@@ -24,6 +23,20 @@ module Elelem
|
|
|
24
23
|
agent.repl
|
|
25
24
|
end
|
|
26
25
|
|
|
26
|
+
desc "files", "Generate CXML of the files"
|
|
27
|
+
def files
|
|
28
|
+
puts '<documents>'
|
|
29
|
+
$stdin.read.split("\n").map(&:strip).reject(&:empty?).each_with_index do |file, i|
|
|
30
|
+
next unless File.file?(file)
|
|
31
|
+
|
|
32
|
+
puts " <document index=\"#{i + 1}\">"
|
|
33
|
+
puts " <source><![CDATA[#{file}]]></source>"
|
|
34
|
+
puts " <document_content><![CDATA[#{File.read(file)}]]></document_content>"
|
|
35
|
+
puts " </document>"
|
|
36
|
+
end
|
|
37
|
+
puts '</documents>'
|
|
38
|
+
end
|
|
39
|
+
|
|
27
40
|
desc "version", "The version of this CLI"
|
|
28
41
|
def version
|
|
29
42
|
say "v#{Elelem::VERSION}"
|
data/lib/elelem/conversation.rb
CHANGED
|
@@ -45,19 +45,19 @@ module Elelem
|
|
|
45
45
|
|
|
46
46
|
case mode.sort
|
|
47
47
|
when [:read]
|
|
48
|
-
"#{base}\n\
|
|
48
|
+
"#{base}\n\nYou may read files on the system."
|
|
49
49
|
when [:write]
|
|
50
|
-
"#{base}\n\
|
|
50
|
+
"#{base}\n\nYou may write files on the system."
|
|
51
51
|
when [:execute]
|
|
52
|
-
"#{base}\n\
|
|
52
|
+
"#{base}\n\nYou may execute shell commands on the system."
|
|
53
53
|
when [:read, :write]
|
|
54
|
-
"#{base}\n\
|
|
54
|
+
"#{base}\n\nYou may read and write files on the system."
|
|
55
55
|
when [:execute, :read]
|
|
56
|
-
"#{base}\n\
|
|
56
|
+
"#{base}\n\nYou may execute shell commands and read files on the system."
|
|
57
57
|
when [:execute, :write]
|
|
58
|
-
"#{base}\n\
|
|
58
|
+
"#{base}\n\nYou may execute shell commands and write files on the system."
|
|
59
59
|
when [:execute, :read, :write]
|
|
60
|
-
"#{base}\n\nYou
|
|
60
|
+
"#{base}\n\nYou may read files, write files and execute shell commands on the system."
|
|
61
61
|
else
|
|
62
62
|
base
|
|
63
63
|
end
|
|
@@ -1,5 +1,15 @@
|
|
|
1
1
|
You are a reasoning coding and system agent.
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
3
|
+
## System
|
|
4
|
+
|
|
5
|
+
Operating System: <%= `uname -a` %>
|
|
6
|
+
USER: <%= ENV['USER'] %>
|
|
7
|
+
HOME: <%= ENV['HOME'] %>
|
|
8
|
+
SHELL: <%= ENV['SHELL'] %>
|
|
9
|
+
PATH: <%= ENV['PATH'] %>
|
|
10
|
+
PWD: <%= ENV['PWD'] %>
|
|
11
|
+
LANG: <%= ENV['LANG'] %>
|
|
12
|
+
EDITOR: <%= ENV['EDITOR'] %>
|
|
13
|
+
LOGNAME: <%= ENV['LOGNAME'] %>
|
|
14
|
+
TERM: <%= ENV['TERM'] %>
|
|
15
|
+
MAIL: <%= ENV['MAIL'] %>
|
data/lib/elelem/tool.rb
CHANGED
|
@@ -11,14 +11,15 @@ module Elelem
|
|
|
11
11
|
end
|
|
12
12
|
|
|
13
13
|
def call(args)
|
|
14
|
-
|
|
14
|
+
unless valid?(args)
|
|
15
|
+
return { error: "Invalid args for #{@name}", received: args.keys, expected: @schema.dig(:function, :parameters, :required) }
|
|
16
|
+
end
|
|
15
17
|
|
|
16
18
|
@block.call(args)
|
|
17
19
|
end
|
|
18
20
|
|
|
19
21
|
def valid?(args)
|
|
20
|
-
|
|
21
|
-
true
|
|
22
|
+
JSON::Validator.validate(@schema.dig(:function, :parameters), args)
|
|
22
23
|
end
|
|
23
24
|
|
|
24
25
|
def to_h
|
data/lib/elelem/toolbox.rb
CHANGED
|
@@ -8,7 +8,7 @@ module Elelem
|
|
|
8
8
|
full_path.exist? ? { content: full_path.read } : { error: "File not found: #{path}" }
|
|
9
9
|
end
|
|
10
10
|
|
|
11
|
-
|
|
11
|
+
BASH_TOOL = Tool.build("bash", "Run shell commands. For git: bash({\"cmd\": \"git\", \"args\": [\"log\", \"--oneline\"]}). Returns stdout/stderr/exit_status.", { cmd: { type: "string" }, args: { type: "array", items: { type: "string" } }, env: { type: "object", additionalProperties: { type: "string" } }, cwd: { type: "string", description: "Working directory (defaults to current)" }, stdin: { type: "string" } }, ["cmd"]) do |args|
|
|
12
12
|
Elelem.shell.execute(
|
|
13
13
|
args["cmd"],
|
|
14
14
|
args: args["args"] || [],
|
|
@@ -42,7 +42,7 @@ module Elelem
|
|
|
42
42
|
@tools_by_name = {}
|
|
43
43
|
@tools = { read: [], write: [], execute: [] }
|
|
44
44
|
add_tool(eval_tool(binding), :execute)
|
|
45
|
-
add_tool(
|
|
45
|
+
add_tool(BASH_TOOL, :execute)
|
|
46
46
|
add_tool(GREP_TOOL, :read)
|
|
47
47
|
add_tool(LIST_TOOL, :read)
|
|
48
48
|
add_tool(PATCH_TOOL, :write)
|
data/lib/elelem/version.rb
CHANGED
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: elelem
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.4.
|
|
4
|
+
version: 0.4.2
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- mo khan
|
|
@@ -198,14 +198,14 @@ files:
|
|
|
198
198
|
- lib/elelem/tool.rb
|
|
199
199
|
- lib/elelem/toolbox.rb
|
|
200
200
|
- lib/elelem/version.rb
|
|
201
|
-
homepage: https://
|
|
201
|
+
homepage: https://github.com/xlgmokha/elelem
|
|
202
202
|
licenses:
|
|
203
203
|
- MIT
|
|
204
204
|
metadata:
|
|
205
205
|
allowed_push_host: https://rubygems.org
|
|
206
|
-
homepage_uri: https://
|
|
207
|
-
source_code_uri: https://
|
|
208
|
-
changelog_uri: https://
|
|
206
|
+
homepage_uri: https://github.com/xlgmokha/elelem
|
|
207
|
+
source_code_uri: https://github.com/xlgmokha/elelem
|
|
208
|
+
changelog_uri: https://github.com/xlgmokha/elelem/blob/main/CHANGELOG.md
|
|
209
209
|
rdoc_options: []
|
|
210
210
|
require_paths:
|
|
211
211
|
- lib
|