rails-llm 0.1.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 +7 -0
- data/Gemfile +4 -0
- data/LICENSE +13 -0
- data/README.md +127 -0
- data/app/assets/images/llm.png +0 -0
- data/app/assets/javascripts/rails_llm/application.js +188 -0
- data/app/controllers/rails_llm/agents_controller.rb +63 -0
- data/app/views/layouts/rails_llm/application.html.erb +410 -0
- data/app/views/rails_llm/agents/_message.html.erb +10 -0
- data/app/views/rails_llm/agents/index.html.erb +21 -0
- data/app/views/rails_llm/agents/show.html.erb +30 -0
- data/config/routes.rb +11 -0
- data/lib/generators/rails_llm/install_generator.rb +43 -0
- data/lib/generators/rails_llm/templates/agent_model.rb.tt +25 -0
- data/lib/generators/rails_llm/templates/initializer.rb.tt +8 -0
- data/lib/generators/rails_llm/templates/knowledge_tool.rb.tt +61 -0
- data/lib/generators/rails_llm/templates/migration.rb.tt +9 -0
- data/lib/generators/rails_llm/ui_generator.rb +28 -0
- data/lib/rails-llm.rb +47 -0
- data/lib/rails_llm/engine.rb +27 -0
- data/lib/rails_llm/stream.rb +69 -0
- data/lib/rails_llm/version.rb +5 -0
- data/lib/rails_llm.rb +3 -0
- data/rails-llm.gemspec +47 -0
- metadata +183 -0
data/lib/rails-llm.rb
ADDED
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module RailsLLM
|
|
4
|
+
extend self
|
|
5
|
+
|
|
6
|
+
require "rails"
|
|
7
|
+
require "llm"
|
|
8
|
+
require "redcarpet"
|
|
9
|
+
require "active_support/inflector"
|
|
10
|
+
require_relative "rails_llm/version"
|
|
11
|
+
require_relative "rails_llm/stream"
|
|
12
|
+
require_relative "rails_llm/engine"
|
|
13
|
+
|
|
14
|
+
##
|
|
15
|
+
# @param [String] text
|
|
16
|
+
# @return [String]
|
|
17
|
+
def markdown(text)
|
|
18
|
+
renderer.render(text)
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
##
|
|
22
|
+
# @return [Redcarpet::Markdown]
|
|
23
|
+
def renderer
|
|
24
|
+
@renderer ||= Redcarpet::Markdown.new(
|
|
25
|
+
Renderer,
|
|
26
|
+
fenced_code_blocks: true,
|
|
27
|
+
tables: true
|
|
28
|
+
)
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
##
|
|
32
|
+
# @api private
|
|
33
|
+
class Renderer < Redcarpet::Render::HTML
|
|
34
|
+
def block_code(code, language)
|
|
35
|
+
language = language.to_s.strip
|
|
36
|
+
klass = language.empty? ? nil : "language-#{language}"
|
|
37
|
+
code = ERB::Util.html_escape(code)
|
|
38
|
+
if klass
|
|
39
|
+
%(<pre><code class="#{klass}">#{code}</code></pre>)
|
|
40
|
+
else
|
|
41
|
+
%(<pre><code>#{code}</code></pre>)
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
ActiveSupport::Inflector.inflections(:en) { _1.acronym "LLM" }
|
|
47
|
+
end
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module RailsLLM
|
|
4
|
+
##
|
|
5
|
+
# {RailsLLM::Engine} is the Rails engine that mounts the chat UI
|
|
6
|
+
# and provides the generator infrastructure.
|
|
7
|
+
class Engine < ::Rails::Engine
|
|
8
|
+
isolate_namespace RailsLLM
|
|
9
|
+
|
|
10
|
+
config.generators do |g|
|
|
11
|
+
g.test_framework :rspec, fixture: false
|
|
12
|
+
g.assets false
|
|
13
|
+
g.helper false
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
initializer "rails_llm.assets" do |app|
|
|
17
|
+
next unless app.config.respond_to?(:assets)
|
|
18
|
+
app.config.assets.precompile += %w[rails_llm/application.css rails_llm/application.js]
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
initializer "rails_llm.active_record" do
|
|
22
|
+
ActiveSupport.on_load(:active_record) do
|
|
23
|
+
require "llm/active_record"
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
end
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "llm"
|
|
4
|
+
|
|
5
|
+
module RailsLLM
|
|
6
|
+
##
|
|
7
|
+
# {Stream} enriches llm.rb's streaming with structured events
|
|
8
|
+
# for the chat UI. Captures content, reasoning, tool calls,
|
|
9
|
+
# and tool returns as structured events.
|
|
10
|
+
class Stream < LLM::Stream
|
|
11
|
+
attr_reader :reasoning_content, :tool_calls
|
|
12
|
+
|
|
13
|
+
def initialize(stream)
|
|
14
|
+
@stream = stream
|
|
15
|
+
@reasoning_content = +""
|
|
16
|
+
@tool_calls = []
|
|
17
|
+
@buffer = +""
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
##
|
|
21
|
+
# @param [String] content
|
|
22
|
+
# @return [void]
|
|
23
|
+
def on_content(content)
|
|
24
|
+
@buffer << content
|
|
25
|
+
write(type: "content", content: RailsLLM.markdown(@buffer))
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
##
|
|
29
|
+
# @param [String] content
|
|
30
|
+
# @return [void]
|
|
31
|
+
def on_reasoning_content(content)
|
|
32
|
+
@reasoning_content << content
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
##
|
|
36
|
+
# @param [LLM::Function] tool
|
|
37
|
+
# @param [String, nil] error
|
|
38
|
+
# @return [void]
|
|
39
|
+
def on_tool_call(tool, error)
|
|
40
|
+
if error
|
|
41
|
+
queue << error
|
|
42
|
+
else
|
|
43
|
+
@tool_calls << {name: tool.name, arguments: tool.arguments}
|
|
44
|
+
write(type: "tool_call", name: tool.name, arguments: tool.arguments)
|
|
45
|
+
queue << ctx.spawn(tool, :call)
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
##
|
|
50
|
+
# @param [LLM::Function] tool
|
|
51
|
+
# @param [LLM::Function::Return] result
|
|
52
|
+
# @return [void]
|
|
53
|
+
def on_tool_return(tool, result)
|
|
54
|
+
write(type: "tool_return", name: tool.name, result: result.value)
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
##
|
|
58
|
+
# @return [void]
|
|
59
|
+
def finish
|
|
60
|
+
write(type: "done")
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
private
|
|
64
|
+
|
|
65
|
+
def write(payload)
|
|
66
|
+
@stream.write("#{LLM.json.dump(payload)}\n")
|
|
67
|
+
end
|
|
68
|
+
end
|
|
69
|
+
end
|
data/lib/rails_llm.rb
ADDED
data/rails-llm.gemspec
ADDED
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require_relative "lib/rails_llm/version"
|
|
4
|
+
|
|
5
|
+
Gem::Specification.new do |spec|
|
|
6
|
+
spec.name = "rails-llm"
|
|
7
|
+
spec.version = RailsLLM::VERSION
|
|
8
|
+
spec.authors = ["0x1eef"]
|
|
9
|
+
spec.email = ["0x1eef@hardenedbsd.org"]
|
|
10
|
+
|
|
11
|
+
spec.description = <<~DESC.strip
|
|
12
|
+
RailsLLM integrates the llm.rb runtime and its features into Rails.
|
|
13
|
+
|
|
14
|
+
RailsLLM extends the builtin ActiveRecord support available to the llm.rb
|
|
15
|
+
runtime with a Rails integration that includes generators for getting set up quickly,
|
|
16
|
+
and an engine for a stream-capable chat interface that can be extended with your
|
|
17
|
+
own tools.
|
|
18
|
+
|
|
19
|
+
The llm.rb runtime runs on Ruby's standard library by default. loads optional pieces
|
|
20
|
+
only when needed, and offers a single runtime for providers, agents, tools, skills, MCP,
|
|
21
|
+
A2A (Agent2Agent), RAG (vector stores & embeddings), streaming, files, and persisted state.
|
|
22
|
+
DESC
|
|
23
|
+
spec.summary = spec.description
|
|
24
|
+
|
|
25
|
+
spec.homepage = "https://github.com/llmrb/rails-llm"
|
|
26
|
+
spec.license = "0BSD"
|
|
27
|
+
spec.required_ruby_version = ">= 3.1.0"
|
|
28
|
+
|
|
29
|
+
spec.metadata["homepage_uri"] = spec.homepage
|
|
30
|
+
spec.metadata["source_code_uri"] = spec.homepage
|
|
31
|
+
spec.metadata["changelog_uri"] = "#{spec.homepage}/releases"
|
|
32
|
+
spec.metadata["documentation_uri"] = "https://0x1eef.github.io/x/llm.rb"
|
|
33
|
+
spec.metadata["rubygems_mfa_required"] = "true"
|
|
34
|
+
|
|
35
|
+
spec.files = Dir["lib/**/*", "app/**/*", "config/**/*"] +
|
|
36
|
+
%w[README.md LICENSE Gemfile rails-llm.gemspec]
|
|
37
|
+
spec.require_paths = ["lib"]
|
|
38
|
+
|
|
39
|
+
spec.add_dependency "llm.rb", "~> 11.0"
|
|
40
|
+
spec.add_dependency "redcarpet", "~> 3.6"
|
|
41
|
+
spec.add_dependency "railties", ">= 7.0"
|
|
42
|
+
spec.add_dependency "actioncable", ">= 7.0"
|
|
43
|
+
spec.add_dependency "activerecord", ">= 7.0"
|
|
44
|
+
|
|
45
|
+
spec.add_development_dependency "rspec-rails"
|
|
46
|
+
spec.add_development_dependency "sqlite3"
|
|
47
|
+
end
|
metadata
ADDED
|
@@ -0,0 +1,183 @@
|
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
|
2
|
+
name: rails-llm
|
|
3
|
+
version: !ruby/object:Gem::Version
|
|
4
|
+
version: 0.1.0
|
|
5
|
+
platform: ruby
|
|
6
|
+
authors:
|
|
7
|
+
- '0x1eef'
|
|
8
|
+
bindir: bin
|
|
9
|
+
cert_chain: []
|
|
10
|
+
date: 1980-01-02 00:00:00.000000000 Z
|
|
11
|
+
dependencies:
|
|
12
|
+
- !ruby/object:Gem::Dependency
|
|
13
|
+
name: llm.rb
|
|
14
|
+
requirement: !ruby/object:Gem::Requirement
|
|
15
|
+
requirements:
|
|
16
|
+
- - "~>"
|
|
17
|
+
- !ruby/object:Gem::Version
|
|
18
|
+
version: '11.0'
|
|
19
|
+
type: :runtime
|
|
20
|
+
prerelease: false
|
|
21
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
22
|
+
requirements:
|
|
23
|
+
- - "~>"
|
|
24
|
+
- !ruby/object:Gem::Version
|
|
25
|
+
version: '11.0'
|
|
26
|
+
- !ruby/object:Gem::Dependency
|
|
27
|
+
name: redcarpet
|
|
28
|
+
requirement: !ruby/object:Gem::Requirement
|
|
29
|
+
requirements:
|
|
30
|
+
- - "~>"
|
|
31
|
+
- !ruby/object:Gem::Version
|
|
32
|
+
version: '3.6'
|
|
33
|
+
type: :runtime
|
|
34
|
+
prerelease: false
|
|
35
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
36
|
+
requirements:
|
|
37
|
+
- - "~>"
|
|
38
|
+
- !ruby/object:Gem::Version
|
|
39
|
+
version: '3.6'
|
|
40
|
+
- !ruby/object:Gem::Dependency
|
|
41
|
+
name: railties
|
|
42
|
+
requirement: !ruby/object:Gem::Requirement
|
|
43
|
+
requirements:
|
|
44
|
+
- - ">="
|
|
45
|
+
- !ruby/object:Gem::Version
|
|
46
|
+
version: '7.0'
|
|
47
|
+
type: :runtime
|
|
48
|
+
prerelease: false
|
|
49
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
50
|
+
requirements:
|
|
51
|
+
- - ">="
|
|
52
|
+
- !ruby/object:Gem::Version
|
|
53
|
+
version: '7.0'
|
|
54
|
+
- !ruby/object:Gem::Dependency
|
|
55
|
+
name: actioncable
|
|
56
|
+
requirement: !ruby/object:Gem::Requirement
|
|
57
|
+
requirements:
|
|
58
|
+
- - ">="
|
|
59
|
+
- !ruby/object:Gem::Version
|
|
60
|
+
version: '7.0'
|
|
61
|
+
type: :runtime
|
|
62
|
+
prerelease: false
|
|
63
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
64
|
+
requirements:
|
|
65
|
+
- - ">="
|
|
66
|
+
- !ruby/object:Gem::Version
|
|
67
|
+
version: '7.0'
|
|
68
|
+
- !ruby/object:Gem::Dependency
|
|
69
|
+
name: activerecord
|
|
70
|
+
requirement: !ruby/object:Gem::Requirement
|
|
71
|
+
requirements:
|
|
72
|
+
- - ">="
|
|
73
|
+
- !ruby/object:Gem::Version
|
|
74
|
+
version: '7.0'
|
|
75
|
+
type: :runtime
|
|
76
|
+
prerelease: false
|
|
77
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
78
|
+
requirements:
|
|
79
|
+
- - ">="
|
|
80
|
+
- !ruby/object:Gem::Version
|
|
81
|
+
version: '7.0'
|
|
82
|
+
- !ruby/object:Gem::Dependency
|
|
83
|
+
name: rspec-rails
|
|
84
|
+
requirement: !ruby/object:Gem::Requirement
|
|
85
|
+
requirements:
|
|
86
|
+
- - ">="
|
|
87
|
+
- !ruby/object:Gem::Version
|
|
88
|
+
version: '0'
|
|
89
|
+
type: :development
|
|
90
|
+
prerelease: false
|
|
91
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
92
|
+
requirements:
|
|
93
|
+
- - ">="
|
|
94
|
+
- !ruby/object:Gem::Version
|
|
95
|
+
version: '0'
|
|
96
|
+
- !ruby/object:Gem::Dependency
|
|
97
|
+
name: sqlite3
|
|
98
|
+
requirement: !ruby/object:Gem::Requirement
|
|
99
|
+
requirements:
|
|
100
|
+
- - ">="
|
|
101
|
+
- !ruby/object:Gem::Version
|
|
102
|
+
version: '0'
|
|
103
|
+
type: :development
|
|
104
|
+
prerelease: false
|
|
105
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
106
|
+
requirements:
|
|
107
|
+
- - ">="
|
|
108
|
+
- !ruby/object:Gem::Version
|
|
109
|
+
version: '0'
|
|
110
|
+
description: |-
|
|
111
|
+
RailsLLM integrates the llm.rb runtime and its features into Rails.
|
|
112
|
+
|
|
113
|
+
RailsLLM extends the builtin ActiveRecord support available to the llm.rb
|
|
114
|
+
runtime with a Rails integration that includes generators for getting set up quickly,
|
|
115
|
+
and an engine for a stream-capable chat interface that can be extended with your
|
|
116
|
+
own tools.
|
|
117
|
+
|
|
118
|
+
The llm.rb runtime runs on Ruby's standard library by default. loads optional pieces
|
|
119
|
+
only when needed, and offers a single runtime for providers, agents, tools, skills, MCP,
|
|
120
|
+
A2A (Agent2Agent), RAG (vector stores & embeddings), streaming, files, and persisted state.
|
|
121
|
+
email:
|
|
122
|
+
- 0x1eef@hardenedbsd.org
|
|
123
|
+
executables: []
|
|
124
|
+
extensions: []
|
|
125
|
+
extra_rdoc_files: []
|
|
126
|
+
files:
|
|
127
|
+
- Gemfile
|
|
128
|
+
- LICENSE
|
|
129
|
+
- README.md
|
|
130
|
+
- app/assets/images/llm.png
|
|
131
|
+
- app/assets/javascripts/rails_llm/application.js
|
|
132
|
+
- app/controllers/rails_llm/agents_controller.rb
|
|
133
|
+
- app/views/layouts/rails_llm/application.html.erb
|
|
134
|
+
- app/views/rails_llm/agents/_message.html.erb
|
|
135
|
+
- app/views/rails_llm/agents/index.html.erb
|
|
136
|
+
- app/views/rails_llm/agents/show.html.erb
|
|
137
|
+
- config/routes.rb
|
|
138
|
+
- lib/generators/rails_llm/install_generator.rb
|
|
139
|
+
- lib/generators/rails_llm/templates/agent_model.rb.tt
|
|
140
|
+
- lib/generators/rails_llm/templates/initializer.rb.tt
|
|
141
|
+
- lib/generators/rails_llm/templates/knowledge_tool.rb.tt
|
|
142
|
+
- lib/generators/rails_llm/templates/migration.rb.tt
|
|
143
|
+
- lib/generators/rails_llm/ui_generator.rb
|
|
144
|
+
- lib/rails-llm.rb
|
|
145
|
+
- lib/rails_llm.rb
|
|
146
|
+
- lib/rails_llm/engine.rb
|
|
147
|
+
- lib/rails_llm/stream.rb
|
|
148
|
+
- lib/rails_llm/version.rb
|
|
149
|
+
- rails-llm.gemspec
|
|
150
|
+
homepage: https://github.com/llmrb/rails-llm
|
|
151
|
+
licenses:
|
|
152
|
+
- 0BSD
|
|
153
|
+
metadata:
|
|
154
|
+
homepage_uri: https://github.com/llmrb/rails-llm
|
|
155
|
+
source_code_uri: https://github.com/llmrb/rails-llm
|
|
156
|
+
changelog_uri: https://github.com/llmrb/rails-llm/releases
|
|
157
|
+
documentation_uri: https://0x1eef.github.io/x/llm.rb
|
|
158
|
+
rubygems_mfa_required: 'true'
|
|
159
|
+
rdoc_options: []
|
|
160
|
+
require_paths:
|
|
161
|
+
- lib
|
|
162
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
|
163
|
+
requirements:
|
|
164
|
+
- - ">="
|
|
165
|
+
- !ruby/object:Gem::Version
|
|
166
|
+
version: 3.1.0
|
|
167
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
168
|
+
requirements:
|
|
169
|
+
- - ">="
|
|
170
|
+
- !ruby/object:Gem::Version
|
|
171
|
+
version: '0'
|
|
172
|
+
requirements: []
|
|
173
|
+
rubygems_version: 4.0.6
|
|
174
|
+
specification_version: 4
|
|
175
|
+
summary: RailsLLM integrates the llm.rb runtime and its features into Rails. RailsLLM
|
|
176
|
+
extends the builtin ActiveRecord support available to the llm.rb runtime with a
|
|
177
|
+
Rails integration that includes generators for getting set up quickly, and an engine
|
|
178
|
+
for a stream-capable chat interface that can be extended with your own tools. The
|
|
179
|
+
llm.rb runtime runs on Ruby's standard library by default. loads optional pieces
|
|
180
|
+
only when needed, and offers a single runtime for providers, agents, tools, skills,
|
|
181
|
+
MCP, A2A (Agent2Agent), RAG (vector stores & embeddings), streaming, files, and
|
|
182
|
+
persisted state.
|
|
183
|
+
test_files: []
|