ruby_llm-docker 0.0.1 → 0.3.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/README.md +255 -11
- data/Rakefile +3 -3
- data/examples/docker_chat.rb +269 -0
- data/examples/list_containers.rb +36 -0
- data/examples/test_chat.rb +81 -0
- data/lib/ruby_llm/docker/build_image.rb +110 -0
- data/lib/ruby_llm/docker/copy_to_container.rb +151 -0
- data/lib/ruby_llm/docker/create_container.rb +124 -0
- data/lib/ruby_llm/docker/create_network.rb +115 -0
- data/lib/ruby_llm/docker/create_volume.rb +107 -0
- data/lib/ruby_llm/docker/exec_container.rb +168 -0
- data/lib/ruby_llm/docker/fetch_container_logs.rb +110 -0
- data/lib/ruby_llm/docker/list_containers.rb +65 -0
- data/lib/ruby_llm/docker/list_images.rb +58 -0
- data/lib/ruby_llm/docker/list_networks.rb +59 -0
- data/lib/ruby_llm/docker/list_volumes.rb +59 -0
- data/lib/ruby_llm/docker/pull_image.rb +103 -0
- data/lib/ruby_llm/docker/push_image.rb +124 -0
- data/lib/ruby_llm/docker/recreate_container.rb +119 -0
- data/lib/ruby_llm/docker/remove_container.rb +92 -0
- data/lib/ruby_llm/docker/remove_image.rb +100 -0
- data/lib/ruby_llm/docker/remove_network.rb +84 -0
- data/lib/ruby_llm/docker/remove_volume.rb +94 -0
- data/lib/ruby_llm/docker/run_container.rb +124 -0
- data/lib/ruby_llm/docker/start_container.rb +74 -0
- data/lib/ruby_llm/docker/stop_container.rb +83 -0
- data/lib/ruby_llm/docker/tag_image.rb +111 -0
- data/lib/ruby_llm/docker/version.rb +11 -2
- data/lib/ruby_llm/docker.rb +66 -3
- data/sig/ruby_llm/docker.rbs +1 -1
- metadata +104 -5
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 17035d50b89aaa2e3cfd6409b1a827a3dc9d6e8cc6013e703105b1bce1d6a80e
|
|
4
|
+
data.tar.gz: aac7610a23113ca2b1cad98e1d7eaa88210d069cf7cf9eaedf28736c526b2599
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 152b3442d3130660f7aad1815a7d16918fe20c61a06579f7ab4815a97af25c49cb581c39103b5b08bcf352ad0052cd8e9c601b9e320e2a0606ba3a7ee5b096fa
|
|
7
|
+
data.tar.gz: 041ce68408938affab9523541f1adb283a6c279e69d3b8abdcc6842c47154da1d0441dcb8a44a05f71c1ed382e4624c5d3136d45f5340c17ed8e9b8a96533176
|
data/README.md
CHANGED
|
@@ -1,38 +1,282 @@
|
|
|
1
|
-
#
|
|
1
|
+
# RubyLLM Docker Tools
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
A comprehensive Ruby gem that provides Docker management capabilities through [RubyLLM](https://github.com/afstanton/ruby_llm) tools. This library enables AI assistants and chatbots to interact with Docker containers, images, networks, and volumes programmatically using natural language.
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
**Note:** This gem is a port of the [DockerMCP](https://github.com/afstanton/docker_mcp) gem, adapted to work directly with RubyLLM tools instead of requiring an external MCP server.
|
|
6
6
|
|
|
7
|
-
##
|
|
7
|
+
## ⚠️ Security Warning
|
|
8
|
+
|
|
9
|
+
**This tool is inherently unsafe and should be used with extreme caution.**
|
|
10
|
+
|
|
11
|
+
- **Arbitrary Code Execution**: The `exec_container` tool allows execution of arbitrary commands inside Docker containers
|
|
12
|
+
- **File System Access**: The `copy_to_container` tool can copy files from the host system into containers
|
|
13
|
+
- **Container Management**: Full container lifecycle management including creation, modification, and deletion
|
|
14
|
+
- **Network & Volume Control**: Complete control over Docker networks and volumes
|
|
8
15
|
|
|
9
|
-
|
|
16
|
+
**Recommendations:**
|
|
17
|
+
- Only use in trusted environments
|
|
18
|
+
- Ensure proper Docker daemon security configuration
|
|
19
|
+
- Consider running with restricted Docker permissions
|
|
20
|
+
- Monitor and audit all container operations
|
|
21
|
+
- Be cautious when exposing these tools in production environments
|
|
22
|
+
|
|
23
|
+
## Installation
|
|
10
24
|
|
|
11
25
|
Install the gem and add to the application's Gemfile by executing:
|
|
12
26
|
|
|
13
27
|
```bash
|
|
14
|
-
bundle add
|
|
28
|
+
bundle add ruby_llm-docker
|
|
15
29
|
```
|
|
16
30
|
|
|
17
31
|
If bundler is not being used to manage dependencies, install the gem by executing:
|
|
18
32
|
|
|
19
33
|
```bash
|
|
20
|
-
gem install
|
|
34
|
+
gem install ruby_llm-docker
|
|
21
35
|
```
|
|
22
36
|
|
|
37
|
+
## Prerequisites
|
|
38
|
+
|
|
39
|
+
- Docker Engine installed and running
|
|
40
|
+
- Ruby 3.2+
|
|
41
|
+
- Docker permissions for the user running the application
|
|
42
|
+
- RubyLLM gem
|
|
43
|
+
|
|
23
44
|
## Usage
|
|
24
45
|
|
|
25
|
-
|
|
46
|
+
### Basic Setup
|
|
47
|
+
|
|
48
|
+
```ruby
|
|
49
|
+
require 'ruby_llm/docker'
|
|
50
|
+
|
|
51
|
+
# Create a new chat instance
|
|
52
|
+
chat = RubyLLM::Chat.new(
|
|
53
|
+
api_key: 'your-openai-api-key',
|
|
54
|
+
model: 'gpt-4'
|
|
55
|
+
)
|
|
56
|
+
|
|
57
|
+
# Add all Docker tools to the chat
|
|
58
|
+
RubyLLM::Docker.add_all_tools_to_chat(chat)
|
|
59
|
+
|
|
60
|
+
# Or add individual tools
|
|
61
|
+
chat.tools << RubyLLM::Docker::ListContainers.new
|
|
62
|
+
chat.tools << RubyLLM::Docker::RunContainer.new
|
|
63
|
+
# ... etc
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
### Interactive Command Line Tool
|
|
67
|
+
|
|
68
|
+
This gem includes a ready-to-use interactive command line tool:
|
|
69
|
+
|
|
70
|
+
```bash
|
|
71
|
+
# Set your OpenAI API key
|
|
72
|
+
export OPENAI_API_KEY='your-key-here'
|
|
73
|
+
|
|
74
|
+
# Run the interactive Docker chat
|
|
75
|
+
ruby -r 'ruby_llm/docker' -e "
|
|
76
|
+
require_relative 'examples/docker_chat.rb'
|
|
77
|
+
DockerChat.new.start
|
|
78
|
+
"
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
Or use the included example script:
|
|
82
|
+
|
|
83
|
+
```bash
|
|
84
|
+
ruby examples/docker_chat.rb
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
### Example Usage
|
|
88
|
+
|
|
89
|
+
Once configured, you can interact with Docker using natural language:
|
|
90
|
+
|
|
91
|
+
```ruby
|
|
92
|
+
# List all containers
|
|
93
|
+
response = chat.ask("How many containers are currently running?")
|
|
94
|
+
|
|
95
|
+
# Create and run a new container
|
|
96
|
+
response = chat.ask("Create a new nginx container named 'my-web-server' and expose port 8080")
|
|
97
|
+
|
|
98
|
+
# Execute commands in a container
|
|
99
|
+
response = chat.ask("Check the nginx version in the my-web-server container")
|
|
100
|
+
|
|
101
|
+
# Copy files to a container
|
|
102
|
+
response = chat.ask("Copy my local config.txt file to /etc/nginx/ in the web server container")
|
|
103
|
+
|
|
104
|
+
# View container logs
|
|
105
|
+
response = chat.ask("Show me the logs for the my-web-server container")
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
## 🔨 Available Tools
|
|
109
|
+
|
|
110
|
+
This gem provides 22 comprehensive Docker management tools organized by functionality:
|
|
111
|
+
|
|
112
|
+
### Container Management
|
|
113
|
+
|
|
114
|
+
- **`ListContainers`** - List all Docker containers (running and stopped) with detailed information
|
|
115
|
+
- **`CreateContainer`** - Create a new container from an image without starting it
|
|
116
|
+
- **`RunContainer`** - Create and immediately start a container from an image
|
|
117
|
+
- **`StartContainer`** - Start an existing stopped container
|
|
118
|
+
- **`StopContainer`** - Stop a running container gracefully
|
|
119
|
+
- **`RemoveContainer`** - Delete a container (must be stopped first unless forced)
|
|
120
|
+
- **`RecreateContainer`** - Stop, remove, and recreate a container with the same configuration
|
|
121
|
+
- **`ExecContainer`** ⚠️ - Execute arbitrary commands inside a running container
|
|
122
|
+
- **`FetchContainerLogs`** - Retrieve stdout/stderr logs from a container
|
|
123
|
+
- **`CopyToContainer`** ⚠️ - Copy files or directories from host to container
|
|
124
|
+
|
|
125
|
+
### Image Management
|
|
126
|
+
|
|
127
|
+
- **`ListImages`** - List all Docker images available locally
|
|
128
|
+
- **`PullImage`** - Download an image from a Docker registry
|
|
129
|
+
- **`PushImage`** - Upload an image to a Docker registry
|
|
130
|
+
- **`BuildImage`** - Build a new image from a Dockerfile
|
|
131
|
+
- **`TagImage`** - Create a new tag for an existing image
|
|
132
|
+
- **`RemoveImage`** - Delete an image from local storage
|
|
133
|
+
|
|
134
|
+
### Network Management
|
|
135
|
+
|
|
136
|
+
- **`ListNetworks`** - List all Docker networks
|
|
137
|
+
- **`CreateNetwork`** - Create a new Docker network
|
|
138
|
+
- **`RemoveNetwork`** - Delete a Docker network
|
|
139
|
+
|
|
140
|
+
### Volume Management
|
|
141
|
+
|
|
142
|
+
- **`ListVolumes`** - List all Docker volumes
|
|
143
|
+
- **`CreateVolume`** - Create a new Docker volume for persistent data
|
|
144
|
+
- **`RemoveVolume`** - Delete a Docker volume
|
|
145
|
+
|
|
146
|
+
### Tool Parameters
|
|
147
|
+
|
|
148
|
+
Most tools accept standard Docker parameters:
|
|
149
|
+
- **Container ID/Name**: Can use either the full container ID, short ID, or container name
|
|
150
|
+
- **Image**: Specify images using `name:tag` format (e.g., `nginx:latest`, `ubuntu:22.04`)
|
|
151
|
+
- **Ports**: Use Docker port mapping syntax (e.g., `"8080:80"`)
|
|
152
|
+
- **Volumes**: Use Docker volume mount syntax (e.g., `"/host/path:/container/path"`)
|
|
153
|
+
- **Environment**: Set environment variables as comma-separated `KEY=VALUE` pairs (e.g., `"NODE_ENV=production,PORT=3000"`)
|
|
154
|
+
|
|
155
|
+
## Common Use Cases
|
|
156
|
+
|
|
157
|
+
### Development Environment Setup
|
|
158
|
+
```ruby
|
|
159
|
+
# Ask the AI to set up a development environment
|
|
160
|
+
response = chat.ask("Pull the node:18-alpine image and create a development container
|
|
161
|
+
named 'dev-env' with port 3000 exposed and my current directory mounted as /app")
|
|
162
|
+
|
|
163
|
+
# Install dependencies and start the application
|
|
164
|
+
response = chat.ask("Run 'npm install' in the dev-env container")
|
|
165
|
+
response = chat.ask("Start the application with 'npm start' in the dev-env container")
|
|
166
|
+
```
|
|
167
|
+
|
|
168
|
+
### Container Debugging
|
|
169
|
+
```ruby
|
|
170
|
+
# Check container status and debug issues
|
|
171
|
+
response = chat.ask("Show me all containers and their current status")
|
|
172
|
+
response = chat.ask("Get the logs for the problematic-container")
|
|
173
|
+
response = chat.ask("Check the running processes in the problematic-container")
|
|
174
|
+
response = chat.ask("Show disk usage in the problematic-container")
|
|
175
|
+
```
|
|
176
|
+
|
|
177
|
+
### File Management
|
|
178
|
+
```ruby
|
|
179
|
+
# Copy files to containers using natural language
|
|
180
|
+
response = chat.ask("Copy my local nginx.conf file to /etc/nginx/ in the web-server container")
|
|
181
|
+
response = chat.ask("Copy the entire src directory to /app/ in the app-container")
|
|
182
|
+
```
|
|
183
|
+
|
|
184
|
+
## Error Handling
|
|
185
|
+
|
|
186
|
+
The tools provide detailed error messages for common issues:
|
|
187
|
+
|
|
188
|
+
- **Container Not Found**: When referencing non-existent containers
|
|
189
|
+
- **Image Not Available**: When trying to use images that aren't pulled locally
|
|
190
|
+
- **Permission Denied**: When Docker daemon access is restricted
|
|
191
|
+
- **Network Conflicts**: When creating networks with conflicting configurations
|
|
192
|
+
- **Volume Mount Issues**: When specified paths don't exist or lack permissions
|
|
193
|
+
|
|
194
|
+
All errors include descriptive messages to help diagnose and resolve issues.
|
|
195
|
+
|
|
196
|
+
## Troubleshooting
|
|
197
|
+
|
|
198
|
+
### Docker Daemon Connection Issues
|
|
199
|
+
```bash
|
|
200
|
+
# Check if Docker daemon is running
|
|
201
|
+
docker info
|
|
202
|
+
|
|
203
|
+
# Verify Docker permissions
|
|
204
|
+
docker ps
|
|
205
|
+
```
|
|
206
|
+
|
|
207
|
+
### Container Operation Failures
|
|
208
|
+
- Ensure container IDs/names are correct (ask the AI to list containers)
|
|
209
|
+
- Check if containers are in the expected state (running/stopped)
|
|
210
|
+
- Verify image availability (ask the AI to list available images)
|
|
211
|
+
|
|
212
|
+
### Permission Issues
|
|
213
|
+
- Ensure the user running the application has Docker permissions
|
|
214
|
+
- Consider adding user to the `docker` group: `sudo usermod -aG docker $USER`
|
|
215
|
+
- Verify Docker socket permissions: `ls -la /var/run/docker.sock`
|
|
216
|
+
|
|
217
|
+
## Limitations
|
|
218
|
+
|
|
219
|
+
- **Platform Specific**: Some container operations may behave differently across operating systems
|
|
220
|
+
- **Docker API Version**: Requires compatible Docker Engine API version
|
|
221
|
+
- **Resource Limits**: Large file copies and image operations may timeout
|
|
222
|
+
- **Concurrent Operations**: Heavy concurrent usage may impact performance
|
|
223
|
+
|
|
224
|
+
## Contributing
|
|
225
|
+
|
|
226
|
+
We welcome contributions! Areas for improvement:
|
|
227
|
+
|
|
228
|
+
- **Enhanced Security**: Additional safety checks and permission validation
|
|
229
|
+
- **Better Error Handling**: More specific error messages and recovery suggestions
|
|
230
|
+
- **Performance Optimization**: Streaming for large file operations
|
|
231
|
+
- **Extended Functionality**: Support for Docker Compose, Swarm, etc.
|
|
232
|
+
- **Testing**: Comprehensive test coverage for all tools
|
|
26
233
|
|
|
27
234
|
## Development
|
|
28
235
|
|
|
29
236
|
After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
|
|
30
237
|
|
|
31
|
-
|
|
238
|
+
### Running Tests
|
|
239
|
+
```bash
|
|
240
|
+
# Install dependencies
|
|
241
|
+
bundle install
|
|
32
242
|
|
|
33
|
-
|
|
243
|
+
# Run the test suite
|
|
244
|
+
bundle exec rake spec
|
|
245
|
+
|
|
246
|
+
# Run tests with coverage
|
|
247
|
+
bundle exec rake spec COVERAGE=true
|
|
248
|
+
```
|
|
249
|
+
|
|
250
|
+
### Local Development Setup
|
|
251
|
+
```bash
|
|
252
|
+
# Clone the repository
|
|
253
|
+
git clone https://github.com/afstanton/ruby_llm-docker.git
|
|
254
|
+
cd ruby_llm-docker
|
|
34
255
|
|
|
35
|
-
|
|
256
|
+
# Install dependencies
|
|
257
|
+
bin/setup
|
|
258
|
+
|
|
259
|
+
# Start development console
|
|
260
|
+
bin/console
|
|
261
|
+
|
|
262
|
+
# Build the gem locally
|
|
263
|
+
bundle exec rake build
|
|
264
|
+
|
|
265
|
+
# Install locally built gem
|
|
266
|
+
bundle exec rake install
|
|
267
|
+
```
|
|
268
|
+
|
|
269
|
+
### Testing with RubyLLM
|
|
270
|
+
```bash
|
|
271
|
+
# Test the interactive chat tool
|
|
272
|
+
export OPENAI_API_KEY='your-key-here'
|
|
273
|
+
ruby examples/docker_chat.rb
|
|
274
|
+
|
|
275
|
+
# Test tool loading without API calls
|
|
276
|
+
ruby examples/test_chat.rb
|
|
277
|
+
```
|
|
278
|
+
|
|
279
|
+
To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and the created tag, and push the `.gem` file to [rubygems.org](https://rubygems.org).
|
|
36
280
|
|
|
37
281
|
## License
|
|
38
282
|
|
data/Rakefile
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
require
|
|
4
|
-
require
|
|
3
|
+
require 'bundler/gem_tasks'
|
|
4
|
+
require 'rspec/core/rake_task'
|
|
5
5
|
|
|
6
6
|
RSpec::Core::RakeTask.new(:spec)
|
|
7
7
|
|
|
8
|
-
require
|
|
8
|
+
require 'rubocop/rake_task'
|
|
9
9
|
|
|
10
10
|
RuboCop::RakeTask.new
|
|
11
11
|
|
|
@@ -0,0 +1,269 @@
|
|
|
1
|
+
#!/usr/bin/env ruby
|
|
2
|
+
# frozen_string_literal: true
|
|
3
|
+
|
|
4
|
+
# Docker Chat - Interactive command line tool for RubyLLM
|
|
5
|
+
# A comprehensive chat interface with all Docker management tools available
|
|
6
|
+
# through natural language interaction powered by OpenAI and RubyLLM
|
|
7
|
+
#
|
|
8
|
+
# Prerequisites:
|
|
9
|
+
# - Set OPENAI_API_KEY environment variable
|
|
10
|
+
# - Docker daemon running and accessible
|
|
11
|
+
#
|
|
12
|
+
# Usage:
|
|
13
|
+
# export OPENAI_API_KEY='your-key-here'
|
|
14
|
+
# ruby examples/docker_chat.rb
|
|
15
|
+
#
|
|
16
|
+
# Debug mode:
|
|
17
|
+
# ruby examples/docker_chat.rb --debug # Enable debug output
|
|
18
|
+
# DOCKER_CHAT_DEBUG=true ruby examples/docker_chat.rb # Via environment variable
|
|
19
|
+
#
|
|
20
|
+
# Commands:
|
|
21
|
+
# /exit - Exit the chat
|
|
22
|
+
# /help - Show available Docker tools
|
|
23
|
+
# /tools - List all loaded tools
|
|
24
|
+
# /clear - Clear the screen
|
|
25
|
+
# /debug - Toggle debug mode on/off
|
|
26
|
+
# anything else - Send to OpenAI with Docker tools available
|
|
27
|
+
|
|
28
|
+
require_relative '../lib/ruby_llm/docker'
|
|
29
|
+
require 'io/console'
|
|
30
|
+
|
|
31
|
+
# rubocop:disable Metrics/ClassLength
|
|
32
|
+
|
|
33
|
+
# Interactive Docker chat interface using RubyLLM and OpenAI.
|
|
34
|
+
# Provides natural language interaction with Docker containers, images, networks, and volumes.
|
|
35
|
+
class DockerChat
|
|
36
|
+
def initialize
|
|
37
|
+
check_environment
|
|
38
|
+
configure_ruby_llm
|
|
39
|
+
setup_debug_mode
|
|
40
|
+
setup_chat
|
|
41
|
+
@running = true
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
def start
|
|
45
|
+
show_welcome
|
|
46
|
+
main_loop
|
|
47
|
+
show_goodbye
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
private
|
|
51
|
+
|
|
52
|
+
def check_environment
|
|
53
|
+
return if ENV['OPENAI_API_KEY']
|
|
54
|
+
|
|
55
|
+
puts '❌ Error: Please set OPENAI_API_KEY environment variable'
|
|
56
|
+
puts "Example: export OPENAI_API_KEY='your-api-key-here'"
|
|
57
|
+
exit 1
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
def configure_ruby_llm
|
|
61
|
+
RubyLLM.configure do |config|
|
|
62
|
+
config.openai_api_key = ENV.fetch('OPENAI_API_KEY', nil)
|
|
63
|
+
end
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
def setup_debug_mode
|
|
67
|
+
# Check for debug mode via environment variable or command line argument
|
|
68
|
+
@debug_mode = ENV['DOCKER_CHAT_DEBUG'] == 'true' || ARGV.include?('--debug') || ARGV.include?('-d')
|
|
69
|
+
debug_puts '🐛 Debug mode enabled' if @debug_mode
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
def debug_puts(message)
|
|
73
|
+
puts message if @debug_mode
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
def setup_chat
|
|
77
|
+
# rubocop:disable Layout/BlockAlignment
|
|
78
|
+
# rubocop:disable Style/MultilineBlockChain
|
|
79
|
+
@chat = RubyLLM.chat(model: 'gpt-4')
|
|
80
|
+
.on_tool_call do |tool_call|
|
|
81
|
+
debug_puts "🔧 Calling tool: #{tool_call.name}"
|
|
82
|
+
debug_puts "📝 Arguments: #{tool_call.arguments}"
|
|
83
|
+
end
|
|
84
|
+
.on_tool_result do |result|
|
|
85
|
+
debug_puts "✅ Tool returned: #{result}"
|
|
86
|
+
end
|
|
87
|
+
# rubocop:enable Layout/BlockAlignment
|
|
88
|
+
# rubocop:enable Style/MultilineBlockChain
|
|
89
|
+
|
|
90
|
+
# Add all Docker tools to the chat
|
|
91
|
+
RubyLLM::Docker.add_all_tools_to_chat(@chat)
|
|
92
|
+
|
|
93
|
+
puts '🔧 Loading Docker tools...'
|
|
94
|
+
puts "✅ Loaded #{RubyLLM::Docker.all_tools.size} Docker tools"
|
|
95
|
+
end
|
|
96
|
+
|
|
97
|
+
def show_welcome
|
|
98
|
+
puts "\n#{'=' * 60}"
|
|
99
|
+
puts '🐳 Welcome to Docker Chat!'
|
|
100
|
+
puts ' Interactive CLI with all Docker tools available'
|
|
101
|
+
puts '=' * 60
|
|
102
|
+
puts
|
|
103
|
+
puts '💡 You can ask questions about Docker containers, images, networks, and volumes.'
|
|
104
|
+
puts ' OpenAI has access to all Docker management tools on this system.'
|
|
105
|
+
puts
|
|
106
|
+
puts 'Commands:'
|
|
107
|
+
puts ' /exit - Exit the chat'
|
|
108
|
+
puts ' /help - Show available Docker tools'
|
|
109
|
+
puts ' /tools - List all loaded tools'
|
|
110
|
+
puts ' /clear - Clear the screen'
|
|
111
|
+
puts ' /debug - Toggle debug mode on/off'
|
|
112
|
+
puts
|
|
113
|
+
puts '🚀 Ready! Type your questions or commands...'
|
|
114
|
+
puts
|
|
115
|
+
debug_puts '🐛 Debug mode is currently enabled. Use /debug to toggle.'
|
|
116
|
+
end
|
|
117
|
+
|
|
118
|
+
def main_loop
|
|
119
|
+
while @running
|
|
120
|
+
print "\n🐳 > "
|
|
121
|
+
|
|
122
|
+
begin
|
|
123
|
+
input = gets&.chomp
|
|
124
|
+
|
|
125
|
+
# Handle Ctrl+C or EOF
|
|
126
|
+
if input.nil?
|
|
127
|
+
@running = false
|
|
128
|
+
break
|
|
129
|
+
end
|
|
130
|
+
|
|
131
|
+
process_input(input.strip)
|
|
132
|
+
rescue Interrupt
|
|
133
|
+
puts "\n\n👋 Received interrupt signal. Use /exit to quit cleanly."
|
|
134
|
+
rescue StandardError => e
|
|
135
|
+
puts "❌ Error: #{e.message}"
|
|
136
|
+
puts ' Please try again or type /exit to quit.'
|
|
137
|
+
end
|
|
138
|
+
end
|
|
139
|
+
end
|
|
140
|
+
|
|
141
|
+
def process_input(input)
|
|
142
|
+
return if input.empty?
|
|
143
|
+
|
|
144
|
+
case input.downcase
|
|
145
|
+
when '/exit', '/quit', '/q'
|
|
146
|
+
@running = false
|
|
147
|
+
when '/help', '/h'
|
|
148
|
+
show_help
|
|
149
|
+
when '/tools', '/t'
|
|
150
|
+
show_tools
|
|
151
|
+
when '/clear', '/c'
|
|
152
|
+
clear_screen
|
|
153
|
+
when '/debug', '/d'
|
|
154
|
+
toggle_debug_mode
|
|
155
|
+
when input.start_with?('/')
|
|
156
|
+
puts "❓ Unknown command: #{input}"
|
|
157
|
+
puts ' Type /help for available commands'
|
|
158
|
+
else
|
|
159
|
+
handle_chat_message(input)
|
|
160
|
+
end
|
|
161
|
+
end
|
|
162
|
+
|
|
163
|
+
def handle_chat_message(message)
|
|
164
|
+
puts "\n🤔 Thinking..."
|
|
165
|
+
|
|
166
|
+
begin
|
|
167
|
+
response = @chat.ask(message)
|
|
168
|
+
|
|
169
|
+
puts "\n🤖 OpenAI Response:"
|
|
170
|
+
puts '─' * 50
|
|
171
|
+
puts response.content
|
|
172
|
+
puts '─' * 50
|
|
173
|
+
rescue StandardError => e
|
|
174
|
+
puts "\n❌ Error communicating with OpenAI:"
|
|
175
|
+
puts " #{e.class}: #{e.message}"
|
|
176
|
+
puts ' Please check your API key and network connection.'
|
|
177
|
+
end
|
|
178
|
+
end
|
|
179
|
+
|
|
180
|
+
def show_help
|
|
181
|
+
puts "\n📚 Available Docker Tools:"
|
|
182
|
+
puts '─' * 50
|
|
183
|
+
|
|
184
|
+
tools_by_category = {
|
|
185
|
+
'Container Management' => [
|
|
186
|
+
'ListContainers - List all Docker containers',
|
|
187
|
+
'CreateContainer - Create new containers',
|
|
188
|
+
'RunContainer - Create and start containers',
|
|
189
|
+
'StartContainer - Start stopped containers',
|
|
190
|
+
'StopContainer - Stop running containers',
|
|
191
|
+
'RemoveContainer - Delete containers',
|
|
192
|
+
'RecreateContainer - Recreate containers with same config',
|
|
193
|
+
'ExecContainer - Execute commands inside containers',
|
|
194
|
+
'CopyToContainer - Copy files to containers',
|
|
195
|
+
'FetchContainerLogs - Get container logs'
|
|
196
|
+
],
|
|
197
|
+
'Image Management' => [
|
|
198
|
+
'ListImages - List available Docker images',
|
|
199
|
+
'PullImage - Download images from registries',
|
|
200
|
+
'BuildImage - Build images from Dockerfile',
|
|
201
|
+
'TagImage - Tag images with new names',
|
|
202
|
+
'PushImage - Upload images to registries',
|
|
203
|
+
'RemoveImage - Delete images'
|
|
204
|
+
],
|
|
205
|
+
'Network Management' => [
|
|
206
|
+
'ListNetworks - List Docker networks',
|
|
207
|
+
'CreateNetwork - Create custom networks',
|
|
208
|
+
'RemoveNetwork - Delete networks'
|
|
209
|
+
],
|
|
210
|
+
'Volume Management' => [
|
|
211
|
+
'ListVolumes - List Docker volumes',
|
|
212
|
+
'CreateVolume - Create persistent volumes',
|
|
213
|
+
'RemoveVolume - Delete volumes'
|
|
214
|
+
]
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
tools_by_category.each do |category, tools|
|
|
218
|
+
puts "\n#{category}:"
|
|
219
|
+
tools.each { |tool| puts " • #{tool}" }
|
|
220
|
+
end
|
|
221
|
+
|
|
222
|
+
puts "\n💡 Example questions you can ask:"
|
|
223
|
+
puts " • 'How many containers are running?'"
|
|
224
|
+
puts " • 'Show me all Docker images'"
|
|
225
|
+
puts " • 'Create a new nginx container named web-server'"
|
|
226
|
+
puts " • 'What networks are available?'"
|
|
227
|
+
puts " • 'Pull the latest Ubuntu image'"
|
|
228
|
+
end
|
|
229
|
+
|
|
230
|
+
def show_tools
|
|
231
|
+
puts "\n🔧 Loaded Tools (#{RubyLLM::Docker.all_tools.size}):"
|
|
232
|
+
puts '─' * 30
|
|
233
|
+
|
|
234
|
+
RubyLLM::Docker.all_tools.each_with_index do |tool_class, index|
|
|
235
|
+
tool_name = tool_class.name.split('::').last
|
|
236
|
+
puts "#{(index + 1).to_s.rjust(2)}. #{tool_name}"
|
|
237
|
+
end
|
|
238
|
+
end
|
|
239
|
+
|
|
240
|
+
def clear_screen
|
|
241
|
+
system('clear') || system('cls')
|
|
242
|
+
puts '🐳 Docker Chat - Screen cleared'
|
|
243
|
+
end
|
|
244
|
+
|
|
245
|
+
def toggle_debug_mode
|
|
246
|
+
@debug_mode = !@debug_mode
|
|
247
|
+
status = @debug_mode ? 'enabled' : 'disabled'
|
|
248
|
+
puts "🐛 Debug mode #{status}"
|
|
249
|
+
debug_puts 'Debug output will now be shown for tool calls and results' if @debug_mode
|
|
250
|
+
end
|
|
251
|
+
|
|
252
|
+
def show_goodbye
|
|
253
|
+
puts "\n👋 Thanks for using Docker Chat!"
|
|
254
|
+
puts ' Hope you found it helpful for managing your Docker environment.'
|
|
255
|
+
puts
|
|
256
|
+
end
|
|
257
|
+
end
|
|
258
|
+
# rubocop:enable Metrics/ClassLength
|
|
259
|
+
|
|
260
|
+
# Start the chat if this file is run directly
|
|
261
|
+
if __FILE__ == $PROGRAM_NAME
|
|
262
|
+
begin
|
|
263
|
+
DockerChat.new.start
|
|
264
|
+
rescue StandardError => e
|
|
265
|
+
puts "\n💥 Fatal error: #{e.class} - #{e.message}"
|
|
266
|
+
puts ' Please check your setup and try again.'
|
|
267
|
+
exit 1
|
|
268
|
+
end
|
|
269
|
+
end
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
#!/usr/bin/env ruby
|
|
2
|
+
# frozen_string_literal: true
|
|
3
|
+
|
|
4
|
+
# Example: Using RubyLLM with Docker ListContainers tool
|
|
5
|
+
# This script creates a chat with OpenAI and asks about Docker containers
|
|
6
|
+
|
|
7
|
+
require_relative '../lib/ruby_llm/docker'
|
|
8
|
+
|
|
9
|
+
# Check if OpenAI API key is configured
|
|
10
|
+
unless ENV['OPENAI_API_KEY']
|
|
11
|
+
puts 'Error: Please set OPENAI_API_KEY environment variable'
|
|
12
|
+
puts "Example: export OPENAI_API_KEY='your-api-key-here'"
|
|
13
|
+
exit 1
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
RubyLLM.configure do |config|
|
|
17
|
+
config.openai_api_key = ENV.fetch('OPENAI_API_KEY', nil)
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
begin
|
|
21
|
+
# Create a new RubyLLM chat instance
|
|
22
|
+
chat = RubyLLM.chat(model: 'gpt-4')
|
|
23
|
+
|
|
24
|
+
# Add the ListContainers tool
|
|
25
|
+
chat.with_tool(RubyLLM::Docker::ListContainers)
|
|
26
|
+
|
|
27
|
+
# Ask OpenAI how many containers there are
|
|
28
|
+
puts 'Asking OpenAI about Docker containers...'
|
|
29
|
+
response = chat.ask('How many Docker containers are currently on this system?')
|
|
30
|
+
|
|
31
|
+
puts "\nOpenAI Response:"
|
|
32
|
+
puts response.content
|
|
33
|
+
rescue StandardError => e
|
|
34
|
+
puts "Error: #{e.class} - #{e.message}"
|
|
35
|
+
puts 'This helps us see what needs to be fixed in the ListContainers tool'
|
|
36
|
+
end
|