rails_console_ai 0.13.0 → 0.14.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 +4 -4
- data/CHANGELOG.md +4 -0
- data/README.md +17 -17
- data/app/controllers/rails_console_ai/application_controller.rb +5 -5
- data/app/controllers/rails_console_ai/sessions_controller.rb +1 -1
- data/app/helpers/rails_console_ai/sessions_helper.rb +1 -1
- data/app/models/rails_console_ai/session.rb +2 -2
- data/app/views/layouts/rails_console_ai/application.html.erb +2 -2
- data/config/routes.rb +1 -1
- data/lib/generators/rails_console_ai/install_generator.rb +3 -3
- data/lib/generators/rails_console_ai/templates/initializer.rb +4 -4
- data/lib/rails_console_ai/channel/base.rb +1 -1
- data/lib/rails_console_ai/channel/console.rb +15 -15
- data/lib/rails_console_ai/channel/slack.rb +2 -2
- data/lib/rails_console_ai/configuration.rb +1 -1
- data/lib/rails_console_ai/console_methods.rb +19 -19
- data/lib/rails_console_ai/context_builder.rb +6 -6
- data/lib/rails_console_ai/conversation_engine.rb +29 -29
- data/lib/rails_console_ai/engine.rb +2 -2
- data/lib/rails_console_ai/executor.rb +11 -11
- data/lib/rails_console_ai/providers/anthropic.rb +1 -1
- data/lib/rails_console_ai/providers/base.rb +3 -3
- data/lib/rails_console_ai/providers/bedrock.rb +1 -1
- data/lib/rails_console_ai/providers/local.rb +1 -1
- data/lib/rails_console_ai/providers/openai.rb +1 -1
- data/lib/rails_console_ai/railtie.rb +6 -6
- data/lib/rails_console_ai/repl.rb +1 -1
- data/lib/rails_console_ai/safety_guards.rb +6 -6
- data/lib/rails_console_ai/session_logger.rb +13 -13
- data/lib/rails_console_ai/slack_bot.rb +12 -12
- data/lib/rails_console_ai/storage/base.rb +1 -1
- data/lib/rails_console_ai/storage/file_storage.rb +1 -1
- data/lib/rails_console_ai/tools/code_tools.rb +1 -1
- data/lib/rails_console_ai/tools/memory_tools.rb +4 -4
- data/lib/rails_console_ai/tools/model_tools.rb +1 -1
- data/lib/rails_console_ai/tools/registry.rb +3 -3
- data/lib/rails_console_ai/tools/schema_tools.rb +1 -1
- data/lib/rails_console_ai/version.rb +2 -2
- data/lib/rails_console_ai.rb +14 -14
- data/lib/tasks/rails_console_ai.rake +2 -2
- metadata +1 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 85382da9107682f9e96af6cfe8abc37f83e72e09bba910c825892c8705537675
|
|
4
|
+
data.tar.gz: 191afb47e155da33c711bd1d69a04a07ad2e10c256d9cfb5e8b2bf09f04cb3b8
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 836313ba09d65cd8dff17afe058b3c249c969171da9d1daf8644c519a41640289f86223f9d21ef63d1fdde7286bddf6545bbf70a6f338265d68f8822e3da3a82
|
|
7
|
+
data.tar.gz: 58041e55f589fb87a380516617934fcbcaa13fed0d176284335dfe2ad41491d958a1ffb24beb4a9392a6b76fbbec118faf00a9b0fa48ee38ca7e99eb08b767f7
|
data/CHANGELOG.md
CHANGED
data/README.md
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
#
|
|
1
|
+
# RailsConsoleAi
|
|
2
2
|
|
|
3
3
|
Claude Code for your Rails Console.
|
|
4
4
|
|
|
@@ -49,7 +49,7 @@ Set your API key in the generated initializer or via env var (`ANTHROPIC_API_KEY
|
|
|
49
49
|
|
|
50
50
|
```ruby
|
|
51
51
|
# config/initializers/rails_console_ai.rb
|
|
52
|
-
|
|
52
|
+
RailsConsoleAi.configure do |config|
|
|
53
53
|
config.api_key = 'sk-ant-...'
|
|
54
54
|
end
|
|
55
55
|
```
|
|
@@ -112,7 +112,7 @@ Safety guards prevent AI-generated code from causing side effects. When a guard
|
|
|
112
112
|
### Built-in Guards
|
|
113
113
|
|
|
114
114
|
```ruby
|
|
115
|
-
|
|
115
|
+
RailsConsoleAi.configure do |config|
|
|
116
116
|
config.use_builtin_safety_guard :database_writes # blocks INSERT/UPDATE/DELETE/DROP/etc.
|
|
117
117
|
config.use_builtin_safety_guard :http_mutations # blocks POST/PUT/PATCH/DELETE via Net::HTTP
|
|
118
118
|
config.use_builtin_safety_guard :mailers # disables ActionMailer delivery
|
|
@@ -128,17 +128,17 @@ end
|
|
|
128
128
|
Write your own guards using the around-block pattern:
|
|
129
129
|
|
|
130
130
|
```ruby
|
|
131
|
-
|
|
131
|
+
RailsConsoleAi.configure do |config|
|
|
132
132
|
config.safety_guard :jobs do |&execute|
|
|
133
133
|
Sidekiq::Testing.fake! { execute.call }
|
|
134
134
|
end
|
|
135
135
|
end
|
|
136
136
|
```
|
|
137
137
|
|
|
138
|
-
Raise `
|
|
138
|
+
Raise `RailsConsoleAi::SafetyError` in your app code to trigger the safe mode prompt:
|
|
139
139
|
|
|
140
140
|
```ruby
|
|
141
|
-
raise
|
|
141
|
+
raise RailsConsoleAi::SafetyError, "Stripe charge blocked"
|
|
142
142
|
```
|
|
143
143
|
|
|
144
144
|
### Toggling Safe Mode
|
|
@@ -149,12 +149,12 @@ raise RailsConsoleAI::SafetyError, "Stripe charge blocked"
|
|
|
149
149
|
|
|
150
150
|
## LLM Providers
|
|
151
151
|
|
|
152
|
-
|
|
152
|
+
RailsConsoleAi supports four LLM providers. Each uses a two-tier model system: a default model for speed/cost, and a thinking model activated via `/think` or by saying "think harder".
|
|
153
153
|
|
|
154
154
|
### Anthropic (default)
|
|
155
155
|
|
|
156
156
|
```ruby
|
|
157
|
-
|
|
157
|
+
RailsConsoleAi.configure do |config|
|
|
158
158
|
config.provider = :anthropic
|
|
159
159
|
config.api_key = 'sk-ant-...' # or set ANTHROPIC_API_KEY env var
|
|
160
160
|
end
|
|
@@ -165,7 +165,7 @@ Default model: `claude-sonnet-4-6`. Thinking model: `claude-opus-4-6`. Prompt ca
|
|
|
165
165
|
### OpenAI
|
|
166
166
|
|
|
167
167
|
```ruby
|
|
168
|
-
|
|
168
|
+
RailsConsoleAi.configure do |config|
|
|
169
169
|
config.provider = :openai
|
|
170
170
|
config.api_key = 'sk-...' # or set OPENAI_API_KEY env var
|
|
171
171
|
end
|
|
@@ -183,7 +183,7 @@ gem 'aws-sdk-bedrockruntime'
|
|
|
183
183
|
```
|
|
184
184
|
|
|
185
185
|
```ruby
|
|
186
|
-
|
|
186
|
+
RailsConsoleAi.configure do |config|
|
|
187
187
|
config.provider = :bedrock
|
|
188
188
|
config.bedrock_region = 'us-east-1'
|
|
189
189
|
# config.model = 'us.anthropic.claude-sonnet-4-6' # default
|
|
@@ -211,7 +211,7 @@ Prompt caching is automatically enabled for Anthropic models on Bedrock, reducin
|
|
|
211
211
|
Run against a local model server. No API key required.
|
|
212
212
|
|
|
213
213
|
```ruby
|
|
214
|
-
|
|
214
|
+
RailsConsoleAi.configure do |config|
|
|
215
215
|
config.provider = :local
|
|
216
216
|
config.local_url = 'http://localhost:11434'
|
|
217
217
|
config.local_model = 'qwen2.5:7b'
|
|
@@ -224,7 +224,7 @@ Timeout is automatically raised to 300s minimum for local models to account for
|
|
|
224
224
|
## Configuration
|
|
225
225
|
|
|
226
226
|
```ruby
|
|
227
|
-
|
|
227
|
+
RailsConsoleAi.configure do |config|
|
|
228
228
|
config.provider = :anthropic # :anthropic, :openai, :bedrock, :local
|
|
229
229
|
config.auto_execute = false # true to skip confirmations
|
|
230
230
|
config.session_logging = true # requires ai_setup
|
|
@@ -241,7 +241,7 @@ The engine mounts a session viewer at `/rails_console_ai`. By default it's open
|
|
|
241
241
|
### Basic Auth
|
|
242
242
|
|
|
243
243
|
```ruby
|
|
244
|
-
|
|
244
|
+
RailsConsoleAi.configure do |config|
|
|
245
245
|
config.admin_username = 'admin'
|
|
246
246
|
config.admin_password = ENV['CONSOLE_AGENT_PASSWORD']
|
|
247
247
|
end
|
|
@@ -252,7 +252,7 @@ end
|
|
|
252
252
|
For apps with their own auth system, pass a proc to `authenticate`. It runs in the controller context, so you have access to `session`, `request`, `redirect_to`, etc.
|
|
253
253
|
|
|
254
254
|
```ruby
|
|
255
|
-
|
|
255
|
+
RailsConsoleAi.configure do |config|
|
|
256
256
|
config.authenticate = proc {
|
|
257
257
|
user = User.find_by(id: session[:user_id])
|
|
258
258
|
unless user&.admin?
|
|
@@ -266,11 +266,11 @@ When `authenticate` is set, `admin_username` / `admin_password` are ignored.
|
|
|
266
266
|
|
|
267
267
|
## Additional Channels
|
|
268
268
|
|
|
269
|
-
|
|
269
|
+
RailsConsoleAi can run through different channels beyond the Rails console. Each channel is a separate process that connects the same AI engine to a different interface.
|
|
270
270
|
|
|
271
271
|
### Slack
|
|
272
272
|
|
|
273
|
-
Run
|
|
273
|
+
Run RailsConsoleAi as a Slack bot. Each Slack thread becomes an independent AI session with full tool use, multi-step plans, and safety guards always on.
|
|
274
274
|
|
|
275
275
|
#### Slack App Setup
|
|
276
276
|
|
|
@@ -299,7 +299,7 @@ Run RailsConsoleAI as a Slack bot. Each Slack thread becomes an independent AI s
|
|
|
299
299
|
#### Configuration
|
|
300
300
|
|
|
301
301
|
```ruby
|
|
302
|
-
|
|
302
|
+
RailsConsoleAi.configure do |config|
|
|
303
303
|
config.slack_bot_token = ENV['SLACK_BOT_TOKEN'] # xoxb-...
|
|
304
304
|
config.slack_app_token = ENV['SLACK_APP_TOKEN'] # xapp-...
|
|
305
305
|
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
module
|
|
1
|
+
module RailsConsoleAi
|
|
2
2
|
class ApplicationController < ActionController::Base
|
|
3
3
|
protect_from_forgery with: :exception
|
|
4
4
|
|
|
@@ -7,18 +7,18 @@ module RailsConsoleAI
|
|
|
7
7
|
private
|
|
8
8
|
|
|
9
9
|
def rails_console_ai_authenticate!
|
|
10
|
-
if (auth =
|
|
10
|
+
if (auth = RailsConsoleAi.configuration.authenticate)
|
|
11
11
|
instance_exec(&auth)
|
|
12
12
|
else
|
|
13
|
-
username =
|
|
14
|
-
password =
|
|
13
|
+
username = RailsConsoleAi.configuration.admin_username
|
|
14
|
+
password = RailsConsoleAi.configuration.admin_password
|
|
15
15
|
|
|
16
16
|
unless username && password
|
|
17
17
|
head :unauthorized
|
|
18
18
|
return
|
|
19
19
|
end
|
|
20
20
|
|
|
21
|
-
authenticate_or_request_with_http_basic('
|
|
21
|
+
authenticate_or_request_with_http_basic('RailsConsoleAi Admin') do |u, p|
|
|
22
22
|
ActiveSupport::SecurityUtils.secure_compare(u, username) &
|
|
23
23
|
ActiveSupport::SecurityUtils.secure_compare(p, password)
|
|
24
24
|
end
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
module
|
|
1
|
+
module RailsConsoleAi
|
|
2
2
|
class Session < ActiveRecord::Base
|
|
3
3
|
self.table_name = 'rails_console_ai_sessions'
|
|
4
4
|
|
|
@@ -11,7 +11,7 @@ module RailsConsoleAI
|
|
|
11
11
|
scope :search, ->(q) { where("name LIKE ? OR query LIKE ?", "%#{q}%", "%#{q}%") }
|
|
12
12
|
|
|
13
13
|
def self.connection
|
|
14
|
-
klass =
|
|
14
|
+
klass = RailsConsoleAi.configuration.connection_class
|
|
15
15
|
if klass
|
|
16
16
|
klass = Object.const_get(klass) if klass.is_a?(String)
|
|
17
17
|
klass.connection
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
<!DOCTYPE html>
|
|
2
2
|
<html>
|
|
3
3
|
<head>
|
|
4
|
-
<title>
|
|
4
|
+
<title>RailsConsoleAi Admin</title>
|
|
5
5
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
|
6
6
|
<style>
|
|
7
7
|
* { margin: 0; padding: 0; box-sizing: border-box; }
|
|
@@ -74,7 +74,7 @@
|
|
|
74
74
|
</head>
|
|
75
75
|
<body>
|
|
76
76
|
<div class="header">
|
|
77
|
-
<h1>
|
|
77
|
+
<h1>RailsConsoleAi Admin</h1>
|
|
78
78
|
<a href="<%= rails_console_ai.root_path %>">Sessions</a>
|
|
79
79
|
</div>
|
|
80
80
|
<div class="container">
|
data/config/routes.rb
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
require 'rails/generators'
|
|
2
2
|
|
|
3
|
-
module
|
|
3
|
+
module RailsConsoleAi
|
|
4
4
|
module Generators
|
|
5
5
|
class InstallGenerator < Rails::Generators::Base
|
|
6
6
|
source_root File.expand_path('templates', __dir__)
|
|
7
|
-
desc 'Creates a
|
|
7
|
+
desc 'Creates a RailsConsoleAi initializer in config/initializers/'
|
|
8
8
|
|
|
9
9
|
def copy_initializer
|
|
10
10
|
template 'initializer.rb', 'config/initializers/rails_console_ai.rb'
|
|
@@ -12,7 +12,7 @@ module RailsConsoleAI
|
|
|
12
12
|
|
|
13
13
|
def show_readme
|
|
14
14
|
say ''
|
|
15
|
-
say '
|
|
15
|
+
say 'RailsConsoleAi installed!', :green
|
|
16
16
|
say ''
|
|
17
17
|
say 'Next steps:'
|
|
18
18
|
say ' 1. Set your API key: export ANTHROPIC_API_KEY=sk-...'
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
|
|
1
|
+
RailsConsoleAi.configure do |config|
|
|
2
2
|
# LLM provider: :anthropic, :openai, or :local
|
|
3
3
|
config.provider = :anthropic
|
|
4
4
|
|
|
@@ -42,14 +42,14 @@ RailsConsoleAI.configure do |config|
|
|
|
42
42
|
# config.debug = true
|
|
43
43
|
|
|
44
44
|
# Session logging: persist AI sessions to the database
|
|
45
|
-
# Run
|
|
45
|
+
# Run RailsConsoleAi.setup! in the Rails console to create the table
|
|
46
46
|
config.session_logging = true
|
|
47
47
|
|
|
48
|
-
# Database connection for
|
|
48
|
+
# Database connection for RailsConsoleAi tables (default: ActiveRecord::Base)
|
|
49
49
|
# Set to a class that responds to .connection if tables live on a different DB
|
|
50
50
|
# config.connection_class = Sharding::CentralizedModel
|
|
51
51
|
|
|
52
|
-
# Admin UI credentials (mount
|
|
52
|
+
# Admin UI credentials (mount RailsConsoleAi::Engine => '/rails_console_ai' in routes.rb)
|
|
53
53
|
# When nil, all requests are denied. Set credentials or use config.authenticate.
|
|
54
54
|
# config.admin_username = 'admin'
|
|
55
55
|
# config.admin_password = 'changeme'
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
require 'readline'
|
|
2
2
|
require 'rails_console_ai/channel/base'
|
|
3
3
|
|
|
4
|
-
module
|
|
4
|
+
module RailsConsoleAi
|
|
5
5
|
module Channel
|
|
6
6
|
class Console < Base
|
|
7
7
|
attr_reader :real_stdout
|
|
@@ -71,7 +71,7 @@ module RailsConsoleAI
|
|
|
71
71
|
end
|
|
72
72
|
|
|
73
73
|
def user_identity
|
|
74
|
-
|
|
74
|
+
RailsConsoleAi.current_user
|
|
75
75
|
end
|
|
76
76
|
|
|
77
77
|
def mode
|
|
@@ -154,10 +154,10 @@ module RailsConsoleAI
|
|
|
154
154
|
end
|
|
155
155
|
|
|
156
156
|
def run_interactive_loop
|
|
157
|
-
auto =
|
|
158
|
-
guards =
|
|
157
|
+
auto = RailsConsoleAi.configuration.auto_execute
|
|
158
|
+
guards = RailsConsoleAi.configuration.safety_guards
|
|
159
159
|
name_display = @engine.session_name ? " (#{@engine.session_name})" : ""
|
|
160
|
-
@real_stdout.puts "\e[
|
|
160
|
+
@real_stdout.puts "\e[36mRailsConsoleAi interactive mode#{name_display}. Type 'exit' or 'quit' to leave.\e[0m"
|
|
161
161
|
safe_info = guards.empty? ? '' : " | Safe mode: #{guards.enabled? ? 'ON' : 'OFF'} (/danger to toggle)"
|
|
162
162
|
@real_stdout.puts "\e[2m Auto-execute: #{auto ? 'ON' : 'OFF'} (Shift-Tab or /auto to toggle)#{safe_info} | > code | /usage | /cost | /compact | /think | /name <label>\e[0m"
|
|
163
163
|
|
|
@@ -220,7 +220,7 @@ module RailsConsoleAI
|
|
|
220
220
|
display_exit_info
|
|
221
221
|
rescue => e
|
|
222
222
|
$stdout = @real_stdout if @real_stdout
|
|
223
|
-
$stderr.puts "\e[
|
|
223
|
+
$stderr.puts "\e[31mRailsConsoleAi Error: #{e.class}: #{e.message}\e[0m"
|
|
224
224
|
end
|
|
225
225
|
|
|
226
226
|
def handle_slash_command(input)
|
|
@@ -228,8 +228,8 @@ module RailsConsoleAI
|
|
|
228
228
|
when '?', '/'
|
|
229
229
|
display_help
|
|
230
230
|
when '/auto'
|
|
231
|
-
|
|
232
|
-
mode =
|
|
231
|
+
RailsConsoleAi.configuration.auto_execute = !RailsConsoleAi.configuration.auto_execute
|
|
232
|
+
mode = RailsConsoleAi.configuration.auto_execute ? 'ON' : 'OFF'
|
|
233
233
|
@real_stdout.puts "\e[36m Auto-execute: #{mode}\e[0m"
|
|
234
234
|
when '/danger'
|
|
235
235
|
toggle_danger
|
|
@@ -238,8 +238,8 @@ module RailsConsoleAI
|
|
|
238
238
|
when '/usage'
|
|
239
239
|
@engine.display_session_summary
|
|
240
240
|
when '/debug'
|
|
241
|
-
|
|
242
|
-
mode =
|
|
241
|
+
RailsConsoleAi.configuration.debug = !RailsConsoleAi.configuration.debug
|
|
242
|
+
mode = RailsConsoleAi.configuration.debug ? 'ON' : 'OFF'
|
|
243
243
|
@real_stdout.puts "\e[36m Debug: #{mode}\e[0m"
|
|
244
244
|
when '/compact'
|
|
245
245
|
@engine.compact_history
|
|
@@ -276,7 +276,7 @@ module RailsConsoleAI
|
|
|
276
276
|
end
|
|
277
277
|
|
|
278
278
|
def toggle_danger
|
|
279
|
-
guards =
|
|
279
|
+
guards = RailsConsoleAi.configuration.safety_guards
|
|
280
280
|
if guards.empty?
|
|
281
281
|
@real_stdout.puts "\e[33m No safety guards configured.\e[0m"
|
|
282
282
|
elsif guards.enabled?
|
|
@@ -289,7 +289,7 @@ module RailsConsoleAI
|
|
|
289
289
|
end
|
|
290
290
|
|
|
291
291
|
def display_safe_status
|
|
292
|
-
guards =
|
|
292
|
+
guards = RailsConsoleAi.configuration.safety_guards
|
|
293
293
|
if guards.empty?
|
|
294
294
|
@real_stdout.puts "\e[33m No safety guards configured.\e[0m"
|
|
295
295
|
else
|
|
@@ -323,8 +323,8 @@ module RailsConsoleAI
|
|
|
323
323
|
end
|
|
324
324
|
|
|
325
325
|
def display_help
|
|
326
|
-
auto =
|
|
327
|
-
guards =
|
|
326
|
+
auto = RailsConsoleAi.configuration.auto_execute ? 'ON' : 'OFF'
|
|
327
|
+
guards = RailsConsoleAi.configuration.safety_guards
|
|
328
328
|
@real_stdout.puts "\e[36m Commands:\e[0m"
|
|
329
329
|
@real_stdout.puts "\e[2m /auto Toggle auto-execute (currently #{auto}) (Shift-Tab)\e[0m"
|
|
330
330
|
unless guards.empty?
|
|
@@ -357,7 +357,7 @@ module RailsConsoleAI
|
|
|
357
357
|
$stdout.puts "\e[2m Resume it: ai_resume #{session_id}\e[0m"
|
|
358
358
|
end
|
|
359
359
|
end
|
|
360
|
-
$stdout.puts "\e[36mLeft
|
|
360
|
+
$stdout.puts "\e[36mLeft RailsConsoleAi interactive mode.\e[0m"
|
|
361
361
|
end
|
|
362
362
|
|
|
363
363
|
# --- Terminal helpers ---
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
require 'rails_console_ai/channel/base'
|
|
2
2
|
|
|
3
|
-
module
|
|
3
|
+
module RailsConsoleAi
|
|
4
4
|
module Channel
|
|
5
5
|
class Slack < Base
|
|
6
6
|
ANSI_REGEX = /\e\[[0-9;]*m/
|
|
@@ -167,7 +167,7 @@ module RailsConsoleAI
|
|
|
167
167
|
text: text
|
|
168
168
|
)
|
|
169
169
|
rescue => e
|
|
170
|
-
|
|
170
|
+
RailsConsoleAi.logger.error("Slack post failed: #{e.message}")
|
|
171
171
|
end
|
|
172
172
|
|
|
173
173
|
def random_thinking_message
|
|
@@ -1,13 +1,13 @@
|
|
|
1
|
-
module
|
|
1
|
+
module RailsConsoleAi
|
|
2
2
|
module ConsoleMethods
|
|
3
3
|
def ai_status
|
|
4
|
-
|
|
4
|
+
RailsConsoleAi.status
|
|
5
5
|
end
|
|
6
6
|
|
|
7
7
|
def ai_memories(n = nil)
|
|
8
8
|
require 'yaml'
|
|
9
9
|
require 'rails_console_ai/tools/memory_tools'
|
|
10
|
-
storage =
|
|
10
|
+
storage = RailsConsoleAi.storage
|
|
11
11
|
keys = storage.list('memories/*.md').sort
|
|
12
12
|
|
|
13
13
|
if keys.empty?
|
|
@@ -48,7 +48,7 @@ module RailsConsoleAI
|
|
|
48
48
|
|
|
49
49
|
def ai_sessions(n = 10, search: nil)
|
|
50
50
|
require 'rails_console_ai/session_logger'
|
|
51
|
-
session_class = Object.const_get('
|
|
51
|
+
session_class = Object.const_get('RailsConsoleAi::Session')
|
|
52
52
|
|
|
53
53
|
scope = session_class.recent
|
|
54
54
|
scope = scope.search(search) if search
|
|
@@ -80,7 +80,7 @@ module RailsConsoleAI
|
|
|
80
80
|
$stdout.puts "\e[2mUse ai_sessions(n, search: \"term\") to filter.\e[0m"
|
|
81
81
|
nil
|
|
82
82
|
rescue => e
|
|
83
|
-
$stderr.puts "\e[
|
|
83
|
+
$stderr.puts "\e[31mRailsConsoleAi error: #{e.message}\e[0m"
|
|
84
84
|
nil
|
|
85
85
|
end
|
|
86
86
|
|
|
@@ -96,8 +96,8 @@ module RailsConsoleAI
|
|
|
96
96
|
session = if identifier
|
|
97
97
|
__find_session(identifier)
|
|
98
98
|
else
|
|
99
|
-
session_class = Object.const_get('
|
|
100
|
-
session_class.where(mode: 'interactive', user_name:
|
|
99
|
+
session_class = Object.const_get('RailsConsoleAi::Session')
|
|
100
|
+
session_class.where(mode: 'interactive', user_name: RailsConsoleAi.current_user).recent.first
|
|
101
101
|
end
|
|
102
102
|
|
|
103
103
|
unless session
|
|
@@ -109,7 +109,7 @@ module RailsConsoleAI
|
|
|
109
109
|
repl = Repl.new(__rails_console_ai_binding)
|
|
110
110
|
repl.resume(session)
|
|
111
111
|
rescue => e
|
|
112
|
-
$stderr.puts "\e[
|
|
112
|
+
$stderr.puts "\e[31mRailsConsoleAi error: #{e.message}\e[0m"
|
|
113
113
|
nil
|
|
114
114
|
end
|
|
115
115
|
|
|
@@ -122,16 +122,16 @@ module RailsConsoleAI
|
|
|
122
122
|
return nil
|
|
123
123
|
end
|
|
124
124
|
|
|
125
|
-
|
|
125
|
+
RailsConsoleAi::SessionLogger.update(session.id, name: new_name)
|
|
126
126
|
$stdout.puts "\e[36mSession ##{session.id} named: #{new_name}\e[0m"
|
|
127
127
|
nil
|
|
128
128
|
rescue => e
|
|
129
|
-
$stderr.puts "\e[
|
|
129
|
+
$stderr.puts "\e[31mRailsConsoleAi error: #{e.message}\e[0m"
|
|
130
130
|
nil
|
|
131
131
|
end
|
|
132
132
|
|
|
133
133
|
def ai_setup
|
|
134
|
-
|
|
134
|
+
RailsConsoleAi.setup!
|
|
135
135
|
end
|
|
136
136
|
|
|
137
137
|
def ai_init
|
|
@@ -143,7 +143,7 @@ module RailsConsoleAI
|
|
|
143
143
|
repl = Repl.new(__rails_console_ai_binding)
|
|
144
144
|
repl.init_guide
|
|
145
145
|
rescue => e
|
|
146
|
-
$stderr.puts "\e[
|
|
146
|
+
$stderr.puts "\e[31mRailsConsoleAi error: #{e.message}\e[0m"
|
|
147
147
|
nil
|
|
148
148
|
end
|
|
149
149
|
|
|
@@ -173,7 +173,7 @@ module RailsConsoleAI
|
|
|
173
173
|
repl = Repl.new(__rails_console_ai_binding)
|
|
174
174
|
repl.one_shot(query.to_s)
|
|
175
175
|
rescue => e
|
|
176
|
-
$stderr.puts "\e[
|
|
176
|
+
$stderr.puts "\e[31mRailsConsoleAi error: #{e.message}\e[0m"
|
|
177
177
|
nil
|
|
178
178
|
end
|
|
179
179
|
|
|
@@ -193,7 +193,7 @@ module RailsConsoleAI
|
|
|
193
193
|
repl.interactive
|
|
194
194
|
end
|
|
195
195
|
rescue => e
|
|
196
|
-
$stderr.puts "\e[
|
|
196
|
+
$stderr.puts "\e[31mRailsConsoleAi error: #{e.message}\e[0m"
|
|
197
197
|
nil
|
|
198
198
|
end
|
|
199
199
|
|
|
@@ -213,14 +213,14 @@ module RailsConsoleAI
|
|
|
213
213
|
repl = Repl.new(__rails_console_ai_binding)
|
|
214
214
|
repl.explain(query.to_s)
|
|
215
215
|
rescue => e
|
|
216
|
-
$stderr.puts "\e[
|
|
216
|
+
$stderr.puts "\e[31mRailsConsoleAi error: #{e.message}\e[0m"
|
|
217
217
|
nil
|
|
218
218
|
end
|
|
219
219
|
|
|
220
220
|
private
|
|
221
221
|
|
|
222
222
|
def __find_session(identifier)
|
|
223
|
-
session_class = Object.const_get('
|
|
223
|
+
session_class = Object.const_get('RailsConsoleAi::Session')
|
|
224
224
|
if identifier.is_a?(Integer)
|
|
225
225
|
session_class.find_by(id: identifier)
|
|
226
226
|
else
|
|
@@ -246,11 +246,11 @@ module RailsConsoleAI
|
|
|
246
246
|
end
|
|
247
247
|
|
|
248
248
|
def __ensure_rails_console_ai_user
|
|
249
|
-
return if
|
|
250
|
-
$stdout.puts "\e[
|
|
249
|
+
return if RailsConsoleAi.current_user
|
|
250
|
+
$stdout.puts "\e[36mRailsConsoleAi logs all AI sessions for audit purposes.\e[0m"
|
|
251
251
|
$stdout.print "\e[36mPlease enter your name: \e[0m"
|
|
252
252
|
name = $stdin.gets.to_s.strip
|
|
253
|
-
|
|
253
|
+
RailsConsoleAi.current_user = name.empty? ? ENV['USER'] : name
|
|
254
254
|
end
|
|
255
255
|
|
|
256
256
|
def __rails_console_ai_binding
|
|
@@ -1,13 +1,13 @@
|
|
|
1
|
-
module
|
|
1
|
+
module RailsConsoleAi
|
|
2
2
|
class ContextBuilder
|
|
3
|
-
def initialize(config =
|
|
3
|
+
def initialize(config = RailsConsoleAi.configuration)
|
|
4
4
|
@config = config
|
|
5
5
|
end
|
|
6
6
|
|
|
7
7
|
def build
|
|
8
8
|
build_smart
|
|
9
9
|
rescue => e
|
|
10
|
-
|
|
10
|
+
RailsConsoleAi.logger.warn("RailsConsoleAi: context build error: #{e.message}")
|
|
11
11
|
smart_system_instructions + "\n\n" + environment_context
|
|
12
12
|
end
|
|
13
13
|
|
|
@@ -90,12 +90,12 @@ module RailsConsoleAI
|
|
|
90
90
|
end
|
|
91
91
|
|
|
92
92
|
def guide_context
|
|
93
|
-
content =
|
|
93
|
+
content = RailsConsoleAi.storage.read(RailsConsoleAi::GUIDE_KEY)
|
|
94
94
|
return nil if content.nil? || content.strip.empty?
|
|
95
95
|
|
|
96
96
|
"## Application Guide\n\n#{content.strip}"
|
|
97
97
|
rescue => e
|
|
98
|
-
|
|
98
|
+
RailsConsoleAi.logger.debug("RailsConsoleAi: guide context failed: #{e.message}")
|
|
99
99
|
nil
|
|
100
100
|
end
|
|
101
101
|
|
|
@@ -112,7 +112,7 @@ module RailsConsoleAI
|
|
|
112
112
|
lines << "Call recall_memories to get details before answering. Do NOT guess from the name alone."
|
|
113
113
|
lines.join("\n")
|
|
114
114
|
rescue => e
|
|
115
|
-
|
|
115
|
+
RailsConsoleAi.logger.debug("RailsConsoleAi: memory context failed: #{e.message}")
|
|
116
116
|
nil
|
|
117
117
|
end
|
|
118
118
|
|