rubycode 0.1.3 → 0.1.4

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.
Files changed (71) hide show
  1. checksums.yaml +4 -4
  2. data/.env.example +38 -0
  3. data/.rubocop.yml +4 -0
  4. data/CHANGELOG.md +52 -0
  5. data/README.md +101 -23
  6. data/USAGE.md +1 -23
  7. data/config/locales/en.yml +208 -1
  8. data/config/system_prompt.md +6 -1
  9. data/config/tools/bash.json +1 -1
  10. data/config/tools/fetch.json +22 -0
  11. data/config/tools/websearch.json +22 -0
  12. data/docs/images/demo.png +0 -0
  13. data/lib/rubycode/adapters/base.rb +92 -2
  14. data/lib/rubycode/adapters/concerns/debugging.rb +32 -0
  15. data/lib/rubycode/adapters/concerns/error_handling.rb +89 -0
  16. data/lib/rubycode/adapters/concerns/http_client.rb +67 -0
  17. data/lib/rubycode/adapters/deepseek.rb +97 -0
  18. data/lib/rubycode/adapters/gemini.rb +133 -0
  19. data/lib/rubycode/adapters/ollama.rb +114 -82
  20. data/lib/rubycode/adapters/openai.rb +97 -0
  21. data/lib/rubycode/adapters/openrouter.rb +102 -0
  22. data/lib/rubycode/agent_loop.rb +110 -18
  23. data/lib/rubycode/client/approval_handler.rb +14 -0
  24. data/lib/rubycode/client/display_formatter.rb +18 -10
  25. data/lib/rubycode/client/response_handler.rb +4 -23
  26. data/lib/rubycode/client.rb +9 -0
  27. data/lib/rubycode/config_manager.rb +81 -0
  28. data/lib/rubycode/configuration.rb +21 -10
  29. data/lib/rubycode/database.rb +19 -0
  30. data/lib/rubycode/errors.rb +12 -0
  31. data/lib/rubycode/models/api_key.rb +118 -0
  32. data/lib/rubycode/models/memory.rb +84 -10
  33. data/lib/rubycode/models.rb +1 -0
  34. data/lib/rubycode/pricing.rb +59 -0
  35. data/lib/rubycode/search_providers/base.rb +66 -0
  36. data/lib/rubycode/search_providers/brave_search.rb +60 -0
  37. data/lib/rubycode/search_providers/concerns/debugging.rb +37 -0
  38. data/lib/rubycode/search_providers/concerns/error_handling.rb +64 -0
  39. data/lib/rubycode/search_providers/concerns/http_client.rb +67 -0
  40. data/lib/rubycode/search_providers/duckduckgo_instant.rb +98 -0
  41. data/lib/rubycode/search_providers/exa_ai.rb +171 -0
  42. data/lib/rubycode/search_providers/multi_provider.rb +47 -0
  43. data/lib/rubycode/token_counter.rb +41 -0
  44. data/lib/rubycode/tools/bash.rb +38 -8
  45. data/lib/rubycode/tools/fetch.rb +120 -0
  46. data/lib/rubycode/tools/web_search.rb +122 -0
  47. data/lib/rubycode/tools.rb +5 -1
  48. data/lib/rubycode/value_objects.rb +8 -4
  49. data/lib/rubycode/version.rb +1 -1
  50. data/lib/rubycode/views/adapter/debug_delay.rb +20 -0
  51. data/lib/rubycode/views/adapter/debug_request.rb +33 -0
  52. data/lib/rubycode/views/adapter/debug_response.rb +31 -0
  53. data/lib/rubycode/views/agent_loop/token_summary.rb +54 -0
  54. data/lib/rubycode/views/agent_loop.rb +2 -0
  55. data/lib/rubycode/views/cli/api_key_missing.rb +37 -0
  56. data/lib/rubycode/views/cli/config_saved.rb +17 -0
  57. data/lib/rubycode/views/cli/configuration_table.rb +3 -3
  58. data/lib/rubycode/views/cli/first_time_setup.rb +17 -0
  59. data/lib/rubycode/views/cli/restart_message.rb +17 -0
  60. data/lib/rubycode/views/cli/setup_title.rb +17 -0
  61. data/lib/rubycode/views/cli.rb +5 -0
  62. data/lib/rubycode/views/formatter/fetch_summary.rb +54 -0
  63. data/lib/rubycode/views/formatter/web_search_summary.rb +53 -0
  64. data/lib/rubycode/views/formatter.rb +2 -0
  65. data/lib/rubycode/views/search_provider/debug_request.rb +30 -0
  66. data/lib/rubycode/views/search_provider/debug_response.rb +31 -0
  67. data/lib/rubycode/views/web_search_approval.rb +29 -0
  68. data/lib/rubycode/views.rb +5 -0
  69. data/lib/rubycode.rb +10 -0
  70. data/rubycode_cli.rb +228 -32
  71. metadata +81 -1
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: b77afd8d1e1731bea1936ffad3ed3e572ce8d14088ebb8fd49570b11c1c7b0b5
4
- data.tar.gz: 2c5abe4b384a4f1f0ef5a26ee4c173eb41124235cd3337147d3fc04a291043b5
3
+ metadata.gz: 38eb208124cc78e03b6a8fb2778309dc17999ed1ab50270fbbfc3635f5d144d2
4
+ data.tar.gz: c02ee8d739bf3162d2e3e2fb5e16adcd00d9a373b3223e6e3d2ae6694f75c22d
5
5
  SHA512:
6
- metadata.gz: 7400478e459c00e8e6ce7889f4eb58667cbe203a30fe4bd64568b122b1d323acb7f08dea92be7b725e4c41547d420fb81c9520071b1c89be3b1a3b6048c4fd1f
7
- data.tar.gz: a6559e94215bf89b6c6cc0ed8a065dce7bae23232e7d3bd7c203ea274644a045a8e003c8e922772575c86f1ea86e0ce56b6fdaed0603535d958c15cd3d35a464
6
+ metadata.gz: 29a2f388ff00077112e5f3697a1fbca342ba5a9974bf7b306c862f4b97f78585c3357366c6980ca5c71c21944e191243ac4e84e59f6451492e140fb711d15314
7
+ data.tar.gz: bc30616c062dd24865f4ec9d2c93cae55569dec5d17c0648d39d6c6aa3059ca91d736b7867e4f0b7015de514182d145b47a5b93e7b297832134f26e922e6e93b
data/.env.example ADDED
@@ -0,0 +1,38 @@
1
+ # RubyCode Environment Variables
2
+ # Copy this file to .env and fill in your API keys
3
+
4
+ # ====================================
5
+ # LLM Providers
6
+ # ====================================
7
+
8
+ # Ollama API Key (required if using Ollama adapter)
9
+ # Get your key: https://ollama.ai/
10
+ # OLLAMA_API_KEY=your_ollama_api_key_here
11
+
12
+ # DeepSeek API Key (required if using DeepSeek adapter)
13
+ # Get your key: https://platform.deepseek.com/api_keys
14
+ # DEEPSEEK_API_KEY=your_deepseek_api_key_here
15
+
16
+ # Gemini API Key (required if using Gemini adapter)
17
+ # Get your key: https://makersuite.google.com/app/apikey
18
+ # GEMINI_API_KEY=your_gemini_api_key_here
19
+
20
+ # OpenAI API Key (required if using OpenAI adapter)
21
+ # Get your key: https://platform.openai.com/api-keys
22
+ # OPENAI_API_KEY=your_openai_api_key_here
23
+
24
+ # OpenRouter API Key (required if using OpenRouter adapter)
25
+ # Get your key: https://openrouter.ai/keys
26
+ # OPENROUTER_API_KEY=your_openrouter_api_key_here
27
+
28
+ # ====================================
29
+ # Web Search Providers
30
+ # ====================================
31
+
32
+ # Exa.ai API Key (optional - enables AI-native web search)
33
+ # Get your key: https://exa.ai/api
34
+ # EXA_API_KEY=your_exa_api_key_here
35
+
36
+ # Brave Search API Key (optional - alternative search provider)
37
+ # Get your key: https://brave.com/search/api/
38
+ # BRAVE_API_KEY=your_brave_api_key_here
data/.rubocop.yml CHANGED
@@ -18,3 +18,7 @@ Metrics/ClassLength:
18
18
 
19
19
  Metrics/MethodLength:
20
20
  Max: 20
21
+
22
+ Metrics/AbcSize:
23
+ Exclude:
24
+ - "test/**/*"
data/CHANGELOG.md CHANGED
@@ -1,5 +1,57 @@
1
1
  ## [Unreleased]
2
2
 
3
+ ## [0.1.4] - 2026-03-07
4
+
5
+ ### Added
6
+ - **Multiple Cloud LLM Adapters**: Support for 5 cloud providers (Ollama Cloud, DeepSeek, Gemini, OpenAI, OpenRouter)
7
+ - **Web Search & Fetch Tools**: Internet search via DuckDuckGo, Brave, and Exa.ai with automatic fallback
8
+ - **Interactive Setup Wizard**: First-time configuration with provider/model selection and API key management
9
+ - **Encrypted API Key Storage**: Secure database storage for API keys with AES-256-GCM encryption
10
+ - **Configuration Persistence**: Automatic saving and loading of user preferences
11
+ - **Search Provider Architecture**: Base class with concerns for HTTP client, error handling, and debugging
12
+ - **Adapter Architecture**: Refactored with base class and shared concerns (66% code reduction)
13
+ - **Debug Mode**: Comprehensive request/response logging for adapters and search providers
14
+ - **Rate Limit Handling**: Automatic detection and retry with 3-attempt limit for 429 errors
15
+
16
+ ### Changed
17
+ - **Bash Tool**: Improved with real-time output streaming and non-interactive execution
18
+ - **System Prompt**: Added web_search and fetch tool documentation for LLM awareness
19
+ - **View Layer**: Enhanced web_search and fetch summaries with full URLs and metadata
20
+ - **Search Providers**: Reduced code duplication from ~100 lines per provider to shared base class
21
+ - **Adapters**: Reduced from ~900 lines to ~300 lines with shared concerns
22
+ - **Memory Management**: Clear conversation history on session start to prevent payload size issues
23
+
24
+ ### Fixed
25
+ - **Agent Loop Exit Bug**: Agent now properly stops when `done` tool is called, even if tool execution fails
26
+ - **Bash Tool stdin_data Error**: Removed invalid stdin_data option from Open3.popen2e
27
+ - **Search Provider Transparency**: Now displays which provider (DuckDuckGo/Brave/Exa) returned results
28
+ - **RuboCop Compliance**: Reduced violations from 45 to 39 (all acceptable complexity metrics)
29
+ - **Test Suite**: Expanded coverage to 141 tests (379 assertions) including adapter and agent loop tests
30
+
31
+ ## [0.1.3] - 2026-03-05
32
+
33
+ ### Added
34
+ - **Write & Update Tools**: New file creation and editing capabilities with user approval workflow
35
+ - **Persistent Memory**: SQLite-backed conversation history using Sequel ORM
36
+ - **Network Resilience**: Automatic retry with exponential backoff for failed LLM requests (configurable timeouts and retries)
37
+ - **Enhanced CLI**: TTY-based interface with formatted output, progress indicators, and approval prompts
38
+ - **I18n Support**: Internationalized error messages and system prompts
39
+ - **Comprehensive Test Suite**: Added test coverage for Database, Memory, and Models::Base classes
40
+ - **Configuration Options**: HTTP timeout settings (read_timeout, open_timeout, max_retries, retry_base_delay)
41
+ - **Cross-platform Support**: Added Linux platform support for CI/CD environments
42
+
43
+ ### Changed
44
+ - Migrated from raw SQLite3 to Sequel ORM for better database abstraction
45
+ - Separated database connection management from model classes
46
+ - Refactored view layer with dedicated view classes for all UI components
47
+ - Improved error handling with adapter-specific error classes
48
+ - Updated gemspec description to be more comprehensive
49
+
50
+ ### Fixed
51
+ - Approval prompt now properly waits for user input instead of auto-declining
52
+ - Models::Base.last now properly orders by ID before retrieving
53
+ - RuboCop compliance across entire codebase
54
+
3
55
  ## [0.1.0] - 2026-02-28
4
56
 
5
57
  - Initial release
data/README.md CHANGED
@@ -16,19 +16,28 @@ A Ruby-native AI coding assistant with pluggable LLM adapters. RubyCode provides
16
16
  ## Features
17
17
 
18
18
  - **AI Agent Loop**: Autonomous task execution with tool calling
19
- - **Pluggable LLM Adapters**: Currently supports Ollama with configurable timeouts and retry logic
19
+ - **Multiple Cloud LLM Adapters**: Support for Ollama Cloud, DeepSeek, Gemini, OpenAI, and OpenRouter
20
+ - **Interactive Setup Wizard**: First-time configuration with provider selection and API key management
20
21
  - **Built-in Tools**:
21
22
  - `bash`: Execute safe bash commands for filesystem exploration
22
23
  - `search`: Search file contents using grep with regex support
23
24
  - `read`: Read files and directories with line numbers
24
25
  - `write`: Create new files with user approval
25
26
  - `update`: Edit existing files with user approval
27
+ - `web_search`: Search the internet with automatic provider fallback (DuckDuckGo/Brave/Exa)
28
+ - `fetch`: Fetch content from URLs
26
29
  - `done`: Signal task completion with final answer
27
30
  - **Persistent Memory**: SQLite-backed conversation history with Sequel ORM
31
+ - **Encrypted API Key Storage**: Secure database storage with AES-256-GCM encryption
32
+ - **Configuration Persistence**: Automatic saving and loading of preferences
28
33
  - **Enhanced CLI**: TTY-based interface with formatted output, progress indicators, and approval workflows
29
- - **Resilient Network**: Automatic retry with exponential backoff for LLM requests
34
+ - **Resilient Network**: Automatic retry with exponential backoff and rate limit handling
35
+ - **Debug Mode**: Comprehensive request/response logging for adapters and search providers
30
36
  - **I18n Support**: Internationalized error messages and UI text
31
- - **Environment Context**: Automatically provides Ruby version, platform, and working directory info
37
+
38
+ ## Requirements
39
+
40
+ - Ruby 3.1 or higher
32
41
 
33
42
  ## Installation
34
43
 
@@ -54,16 +63,30 @@ bundle install
54
63
 
55
64
  ### Basic Usage
56
65
 
66
+ #### Interactive CLI (Recommended)
67
+
68
+ ```bash
69
+ rubycode
70
+ ```
71
+
72
+ The first time you run RubyCode, an interactive setup wizard will guide you through:
73
+ 1. Selecting your LLM provider (Ollama Cloud, DeepSeek, Gemini, OpenAI, or OpenRouter)
74
+ 2. Choosing a model
75
+ 3. Entering API keys (saved securely with encryption)
76
+
77
+ Your configuration is automatically saved and reloaded on subsequent runs.
78
+
79
+ #### Programmatic Usage
80
+
57
81
  ```ruby
58
82
  require "rubycode"
59
83
 
60
84
  # Configure the LLM adapter
61
85
  RubyCode.configure do |config|
62
86
  config.adapter = :ollama
63
- config.url = "http://localhost:11434"
64
- config.model = "deepseek-v3.1:671b-cloud"
87
+ config.url = "https://api.ollama.com"
88
+ config.model = "qwen3-coder:480b-cloud"
65
89
  config.root_path = Dir.pwd
66
- config.debug = false
67
90
  end
68
91
 
69
92
  # Create a client and ask a question
@@ -76,14 +99,13 @@ puts response
76
99
 
77
100
  ```ruby
78
101
  RubyCode.configure do |config|
79
- config.adapter = :ollama # LLM adapter to use
80
- config.url = "http://localhost:11434" # Ollama server URL
81
- config.model = "deepseek-v3.1:671b-cloud" # Model name
102
+ # LLM Provider Settings
103
+ config.adapter = :ollama # :ollama, :deepseek, :gemini, :openai, :openrouter
104
+ config.url = "https://api.ollama.com" # Provider API URL
105
+ config.model = "qwen3-coder:480b-cloud" # Model name
82
106
  config.root_path = Dir.pwd # Project root directory
83
- config.debug = false # Enable debug output
84
- config.enable_tool_injection_workaround = true # Force tool usage (enabled by default)
85
107
 
86
- # HTTP timeout and retry settings (new in 0.1.3)
108
+ # HTTP timeout and retry settings
87
109
  config.http_read_timeout = 120 # Request timeout in seconds (default: 120)
88
110
  config.http_open_timeout = 10 # Connection timeout in seconds (default: 10)
89
111
  config.max_retries = 3 # Number of retry attempts (default: 3)
@@ -91,9 +113,19 @@ RubyCode.configure do |config|
91
113
  end
92
114
  ```
93
115
 
116
+ ### Supported LLM Providers
117
+
118
+ | Provider | Models | API Key Required | Notes |
119
+ |----------|--------|------------------|-------|
120
+ | **Ollama Cloud** | qwen3-coder, deepseek-v3.1, gpt-oss | Yes | Cloud-hosted Ollama models |
121
+ | **DeepSeek** | deepseek-chat, deepseek-reasoner | Yes | Fast reasoning models |
122
+ | **Google Gemini** | gemini-2.5-flash, gemini-2.5-pro, gemini-3-flash-preview | Yes | Multimodal support |
123
+ | **OpenAI** | gpt-4o, gpt-4o-mini, o1 | Yes | GPT models with reasoning |
124
+ | **OpenRouter** | claude-sonnet-4.5, claude-opus-4.6, gpt-4o | Yes | Access to multiple providers |
125
+
94
126
  ### Available Tools
95
127
 
96
- The agent has access to six built-in tools:
128
+ The agent has access to several built-in tools:
97
129
 
98
130
  1. **bash**: Execute safe bash commands including:
99
131
  - Directory exploration: `ls`, `pwd`, `find`, `tree`
@@ -104,25 +136,71 @@ The agent has access to six built-in tools:
104
136
  3. **read**: Read files with line numbers or list directory contents
105
137
  4. **write**: Create new files (requires user approval)
106
138
  5. **update**: Edit existing files with exact string replacement (requires user approval)
107
- 6. **done**: Signal completion and provide the final answer
139
+ 6. **web_search**: Search the internet with automatic provider fallback (requires user approval):
140
+ - Primary: Exa.ai (AI-native search, optional with API key)
141
+ - Fallback 1: DuckDuckGo Instant Answer API (free, no API key)
142
+ - Fallback 2: Brave Search API (optional, for better results)
143
+ 7. **fetch**: Fetch and extract text content from URLs (requires user approval)
144
+ 8. **done**: Signal completion and provide the final answer
108
145
 
109
146
  **Note**: Tool schemas are externalized in `config/tools/*.json` for easy customization.
110
147
 
111
- ### New in 0.1.3
148
+ #### Web Search Configuration
149
+
150
+ **By default** (no setup needed):
151
+ - Uses DuckDuckGo Instant Answer API (free, no CAPTCHA)
152
+ - Good for factual queries and summaries
153
+
154
+ **For AI-native search** (optional, recommended):
155
+ ```bash
156
+ # Sign up at https://exa.ai/api
157
+ export EXA_API_KEY=your_api_key_here
158
+ ```
112
159
 
113
- - **Persistent Memory**: Conversation history now stored in SQLite database using Sequel ORM
114
- - **Write & Update Tools**: Create and modify files with user approval workflow
115
- - **Network Resilience**: Automatic retry with exponential backoff for failed LLM requests
116
- - **Enhanced CLI**: Improved UI with TTY toolkit, formatted output, and progress indicators
117
- - **I18n Support**: Internationalized error messages and system prompts
118
- - **Improved Architecture**: Separated database connection management, view classes for all UI components
119
- - **Cross-platform Support**: Added Linux platform support for CI/CD environments
160
+ **For better web results** (optional):
161
+ ```bash
162
+ # Sign up at https://brave.com/search/api/
163
+ export BRAVE_API_KEY=your_api_key_here
164
+ ```
165
+
166
+ ### New in 0.1.4
167
+
168
+ - **Bug Fix**: Agent now properly stops when `done` tool is called, even if tool execution fails
169
+ - **Multiple Cloud LLM Adapters**: Support for 5 providers (Ollama Cloud, DeepSeek, Gemini, OpenAI, OpenRouter)
170
+ - **Web Search & Fetch Tools**: Internet search with automatic fallback (Exa/DuckDuckGo/Brave)
171
+ - **Interactive Setup Wizard**: First-time configuration with guided setup
172
+ - **Encrypted API Key Storage**: Secure database storage with AES-256-GCM
173
+ - **Configuration Persistence**: Automatic saving/loading of preferences
174
+ - **Search Provider Architecture**: Refactored with base class and shared concerns
175
+ - **Adapter Architecture**: 66% code reduction with shared HTTP/error handling
176
+ - **Debug Mode**: Comprehensive request/response logging
177
+ - **Rate Limit Handling**: Automatic retry with 3-attempt limit for 429 errors
178
+ - **Expanded Test Coverage**: 141 tests covering adapters, agent loop, configuration, and tools
179
+ - **Memory Optimization**: Configurable memory window with tool result pruning
120
180
 
121
181
  ## Development
122
182
 
123
183
  After checking out the repo, run `bundle install` to install dependencies.
124
184
 
125
- To install this gem onto your local machine, run:
185
+ ### Running Tests
186
+
187
+ ```bash
188
+ # Run all tests
189
+ bundle exec rake test
190
+
191
+ # Run tests without warnings
192
+ bundle exec rake test 2>/dev/null
193
+
194
+ # Run specific test file
195
+ bundle exec rake test TEST=test/test_adapters.rb
196
+
197
+ # Run with RuboCop
198
+ bundle exec rake
199
+ ```
200
+
201
+ ### Installing Locally
202
+
203
+ To install this gem onto your local machine:
126
204
 
127
205
  ```bash
128
206
  bundle exec rake install
data/USAGE.md CHANGED
@@ -67,27 +67,5 @@ The agent autonomously decides which tools to use to:
67
67
  Built following OpenCode's design:
68
68
  - **Tools**: Controlled, safe operations with validation
69
69
  - **Agent Loop**: LLM calls tools, we execute, loop until done
70
- - **History**: Maintains conversation context
70
+ - **History**: Maintains conversation context including tool calls
71
71
  - **JSON Visibility**: Full transparency in debug mode
72
-
73
- ## Workaround for Weak Tool-Calling Models
74
-
75
- If you're testing with models that have poor tool-calling capabilities (like qwen3-coder), enable the injection workaround:
76
-
77
- ```ruby
78
- Rubycode.configure do |config|
79
- config.enable_tool_injection_workaround = true
80
- end
81
- ```
82
-
83
- **What this does:**
84
- - When the model generates text instead of calling a tool, it injects a reminder message
85
- - Forces the model to keep calling tools until it finds the answer
86
- - **OpenCode does NOT use this** - they rely on strong tool-calling models (Claude, GPT-4)
87
- - This is ONLY for testing/development with weaker models
88
-
89
- **When to disable:**
90
- - When using Claude (Anthropic)
91
- - When using GPT-4 (OpenAI)
92
- - When using Gemini (Google)
93
- - In production
@@ -11,7 +11,115 @@ en:
11
11
  subtitle: "AI Ruby/Rails Code Assistant"
12
12
  built_with: "Built with: %{stack}"
13
13
  stack: "Ollama + DeepSeek + TTY Toolkit"
14
- commands: "Commands: exit, quit, clear"
14
+ commands: "Commands: exit, quit, clear, config"
15
+
16
+ setup:
17
+ title: "🔧 Configuration Setup"
18
+ first_time: "👋 First-time setup!"
19
+ adapter_prompt: "Select LLM provider:"
20
+ model_prompt: "Select model:"
21
+ custom_model_prompt: "Enter model name:"
22
+ url_prompt: "Ollama URL:"
23
+ api_key_prompt: "%{adapter} API Key:"
24
+ api_key_optional: "(press Enter to use environment variable)"
25
+ api_key_missing: "⚠️ %{adapter}_API_KEY not set!"
26
+ api_key_help: "Get your key: %{url}\nThen either:\n 1. Set environment variable: export %{env_var}='...'\n 2. Enter it when prompted during setup"
27
+ api_key_required: "API key is required to continue."
28
+ use_saved_api_key: "Use saved %{adapter} API key?"
29
+ save_env_key_to_db: "Save %{adapter} API key from environment to database?"
30
+ config_saved: "✓ Configuration saved to %{path}"
31
+ use_saved: "Use saved configuration (%{adapter}/%{model})?"
32
+ reconfigure: "Reconfigure?"
33
+ restart_message: "Restart rubycode to apply new configuration."
34
+ configure_exa: "Configure Exa.ai for web search? (Optional - AI-native search, requires API key)"
35
+
36
+ models:
37
+ ollama:
38
+ default: "qwen3-coder:480b-cloud"
39
+ powerful:
40
+ name: "qwen3-coder:480b-cloud"
41
+ label: "Qwen3 Coder 480B (Best for coding, cloud)"
42
+ advanced:
43
+ name: "gpt-oss:120b-cloud"
44
+ label: "GPT-OSS 120B (Reasoning, cloud)"
45
+ reasoning:
46
+ name: "deepseek-v3.1:671b-cloud"
47
+ label: "DeepSeek v3.1 671B (Advanced reasoning, cloud)"
48
+ fast:
49
+ name: "gpt-oss:20b-cloud"
50
+ label: "GPT-OSS 20B (Fast, cloud)"
51
+ deepseek:
52
+ default: "deepseek-chat"
53
+ fast:
54
+ name: "deepseek-chat"
55
+ label: "DeepSeek Chat (Fast, reasoning)"
56
+ reasoning:
57
+ name: "deepseek-reasoner"
58
+ label: "DeepSeek Reasoner (Advanced, chain-of-thought)"
59
+ gemini:
60
+ default: "gemini-2.5-flash"
61
+ fast:
62
+ name: "gemini-2.5-flash"
63
+ label: "Gemini 2.5 Flash (Fast, latest)"
64
+ lite:
65
+ name: "gemini-2.5-flash-lite"
66
+ label: "Gemini 2.5 Flash Lite (Fastest)"
67
+ powerful:
68
+ name: "gemini-2.5-pro"
69
+ label: "Gemini 2.5 Pro (Most capable)"
70
+ experimental:
71
+ name: "gemini-3-flash-preview"
72
+ label: "Gemini 3 Flash Preview (Experimental)"
73
+ openai:
74
+ default: "gpt-4o"
75
+ fast:
76
+ name: "gpt-4o-mini"
77
+ label: "GPT-4o Mini (Fast, cheap)"
78
+ balanced:
79
+ name: "gpt-4o"
80
+ label: "GPT-4o (Balanced)"
81
+ reasoning:
82
+ name: "o1"
83
+ label: "O1 (Advanced reasoning)"
84
+ openrouter:
85
+ default: "anthropic/claude-sonnet-4.5"
86
+ fast:
87
+ name: "anthropic/claude-haiku-4.5"
88
+ label: "Claude 4.5 Haiku (Fast, cheap)"
89
+ balanced:
90
+ name: "anthropic/claude-sonnet-4.5"
91
+ label: "Claude 4.5 Sonnet (Balanced)"
92
+ powerful:
93
+ name: "anthropic/claude-opus-4.6"
94
+ label: "Claude 4.6 Opus (Most capable)"
95
+ alternative:
96
+ name: "openai/gpt-4o"
97
+ label: "GPT-4o (OpenAI)"
98
+ adapters:
99
+ ollama:
100
+ name: "Ollama (Cloud)"
101
+ api_key_url: "https://ollama.ai/"
102
+ requires_key: true
103
+ deepseek:
104
+ name: "DeepSeek (Cloud - Reasoning Models)"
105
+ api_key_url: "https://platform.deepseek.com/api_keys"
106
+ requires_key: true
107
+ gemini:
108
+ name: "Google Gemini (Cloud - Multimodal)"
109
+ api_key_url: "https://makersuite.google.com/app/apikey"
110
+ requires_key: true
111
+ openai:
112
+ name: "OpenAI (Cloud - GPT Models)"
113
+ api_key_url: "https://platform.openai.com/api-keys"
114
+ requires_key: true
115
+ openrouter:
116
+ name: "OpenRouter (Cloud - Multiple Models)"
117
+ api_key_url: "https://openrouter.ai/keys"
118
+ requires_key: true
119
+ exa:
120
+ name: "Exa.ai (Web Search)"
121
+ api_key_url: "https://exa.ai/api"
122
+ requires_key: true
15
123
 
16
124
  approval:
17
125
  bash:
@@ -69,6 +177,16 @@ en:
69
177
  debug_prefix: "[DEBUG]"
70
178
  error_prefix: "[ERROR]"
71
179
 
180
+ debug:
181
+ request_title: "📤 REQUEST TO LLM"
182
+ request_title_adapter: "📤 REQUEST TO LLM (%{adapter})"
183
+ response_title: "📥 RESPONSE FROM LLM"
184
+ response_title_adapter: "📥 RESPONSE FROM LLM (%{adapter})"
185
+ url_label: "URL: %{url}"
186
+ model_label: "Model: %{model}"
187
+ payload_label: "Payload:"
188
+ separator: "================================================================================"
189
+
72
190
  errors:
73
191
  unknown_adapter: "Unknown Adapter"
74
192
  file_not_found: "File '%{path}' not found"
@@ -85,3 +203,92 @@ en:
85
203
  adapter_connection: "Cannot connect to LLM at %{url}: %{error}"
86
204
  adapter_retry: "Request failed: %{error}. Retrying in %{delay}s... (attempt %{attempt}/%{max_retries})"
87
205
  adapter_failed: "LLM adapter failed: %{error}"
206
+ adapter_retry_exhausted: "All retry attempts failed: %{error}\nPlease check your LLM server connection and try again."
207
+ rate_limit_exhausted: "Rate limit exceeded after %{max_attempts} consecutive attempts. Please wait a few minutes before trying again."
208
+ user_cancelled_search: "USER CANCELLED: The user declined web search for '%{query}'. Do not retry this search. Ask the user if they want to search for something else or call 'done' to finish."
209
+ network_error: "Network error: %{message}"
210
+ http_error: "HTTP %{code}: %{message}"
211
+ url_error: "Invalid URL: %{url}"
212
+ tools_not_supported: |
213
+ Model '%{model}' does not support tool calling.
214
+
215
+ RubyCode requires a model with function/tool calling capabilities.
216
+
217
+ Suggested models that support tools:
218
+ • qwen2.5-coder:7b (pull with: ollama pull qwen2.5-coder:7b)
219
+ • llama3.1:8b (pull with: ollama pull llama3.1:8b)
220
+ • mistral:7b (pull with: ollama pull mistral:7b)
221
+
222
+ Update your configuration in lib/rubycode/configuration.rb to use a compatible model.
223
+
224
+ # Adapter-specific errors
225
+ adapter:
226
+ retry_failed: "Failed after %{max_retries} retries: %{error}"
227
+ invalid_json: "Invalid JSON response from server: %{error}"
228
+ unexpected_error: "Unexpected error: %{error}"
229
+ read_timeout: "Request timed out after %{timeout}s: %{error}"
230
+ open_timeout: "Connection timed out after %{timeout}s: %{error}"
231
+ connection_refused: "Connection refused to %{uri}: %{error}"
232
+ connection_timeout: "Connection timed out to %{uri}: %{error}"
233
+ host_unreachable: "Cannot resolve host %{hostname}: %{error}"
234
+ rate_limited: "Rate limited (%{code}): %{message}"
235
+ server_error: "Server error (%{code}): %{message}"
236
+ http_error: "HTTP error (%{code}): %{message}"
237
+ auth_failed: "Authentication failed (%{code}): Check your %{adapter_name}_API_KEY"
238
+ no_choices: "No choices in response"
239
+ no_message: "No message in choice"
240
+
241
+ # Gemini-specific errors
242
+ gemini:
243
+ api_key_missing: |
244
+ GEMINI_API_KEY environment variable not set.
245
+
246
+ Get your API key:
247
+ https://makersuite.google.com/app/apikey
248
+
249
+ Then set it:
250
+ export GEMINI_API_KEY='...'
251
+
252
+ # OpenAI-specific errors
253
+ openai:
254
+ api_key_missing: |
255
+ OPENAI_API_KEY environment variable not set.
256
+
257
+ Get your API key:
258
+ https://platform.openai.com/api-keys
259
+
260
+ Then set it:
261
+ export OPENAI_API_KEY='sk-...'
262
+
263
+ # OpenRouter-specific errors
264
+ openrouter:
265
+ api_key_missing: |
266
+ OPENROUTER_API_KEY environment variable not set.
267
+
268
+ Get your API key:
269
+ https://openrouter.ai/keys
270
+
271
+ Then set it:
272
+ export OPENROUTER_API_KEY='sk-or-v1-...'
273
+
274
+ # Ollama-specific errors
275
+ ollama:
276
+ api_key_missing: |
277
+ OLLAMA_API_KEY environment variable not set.
278
+
279
+ Get your API key:
280
+ https://ollama.ai/
281
+
282
+ Then set it:
283
+ export OLLAMA_API_KEY='your-api-key'
284
+
285
+ # DeepSeek-specific errors
286
+ deepseek:
287
+ api_key_missing: |
288
+ DEEPSEEK_API_KEY environment variable not set.
289
+
290
+ Get your API key:
291
+ https://platform.deepseek.com/api_keys
292
+
293
+ Then set it:
294
+ export DEEPSEEK_API_KEY='sk-...'
@@ -14,6 +14,8 @@ You MUST call a tool in EVERY response. You MUST NEVER respond with just text.
14
14
  - **read**: view file contents with line numbers
15
15
  - **write**: create new files (requires approval, errors if file exists)
16
16
  - **update**: modify existing files (auto-reads if needed, requires approval)
17
+ - **web_search**: search the internet when you cannot find the answer in the codebase or need current information (requires approval)
18
+ - **fetch**: fetch content from URLs to read documentation or resources (requires approval)
17
19
  - **done**: MUST call when task is complete (see below)
18
20
 
19
21
  ## Recommended workflow
@@ -22,7 +24,10 @@ You MUST call a tool in EVERY response. You MUST NEVER respond with just text.
22
24
  2. Use bash with find to locate files: `find . -name "*.rb"`
23
25
  3. Once found → use read to see the file
24
26
  4. Make changes with write/update if needed
25
- 5. IMMEDIATELY call done when finished - do not continue exploring
27
+ 5. If you cannot find the answer in the codebase or need current/external information:
28
+ - Use web_search to find information on the internet
29
+ - Use fetch to read documentation from URLs
30
+ 6. IMMEDIATELY call done when finished - do not continue exploring
26
31
 
27
32
  ## CRITICAL: When to call 'done'
28
33
 
@@ -2,7 +2,7 @@
2
2
  "type": "function",
3
3
  "function": {
4
4
  "name": "bash",
5
- "description": "Execute safe bash commands for exploring the filesystem and terminal operations.\n\nUse this for any command-line operations including:\n- Directory exploration: ls, find, tree\n- File inspection: cat, head, tail, wc, file\n- Content search: grep, rg (ripgrep)\n\nExamples:\n- grep -rn 'button' app/views\n- find . -name '*.rb' -type f\n- ls -la app/\n\nWhitelisted commands: ls, pwd, find, tree, cat, head, tail, wc, file, which, echo, grep, rg",
5
+ "description": "Execute bash commands and wait for completion. Commands run non-interactively (stdin is closed).\n\nUse this for:\n- Directory exploration: ls, find, tree\n- File inspection: cat, head, tail, wc, file\n- Content search: grep, rg\n- Development tools: bundle, rails, rake, ruby, gem, node, npm, yarn, git (requires approval)\n\nIMPORTANT: For Rails generators and similar tools, always use --force or --skip flags to avoid interactive prompts:\n- rails generate authentication --force (overwrites files)\n- rails generate model User --force\n- bundle install --quiet\n\nExamples:\n- grep -rn 'button' app/views\n- find . -name '*.rb' -type f\n- rails generate authentication --force\n- git status\n\nAuto-approved commands (no user confirmation needed): ls, pwd, find, tree, cat, head, tail, wc, file, which, echo, grep, rg",
6
6
  "parameters": {
7
7
  "type": "object",
8
8
  "properties": {
@@ -0,0 +1,22 @@
1
+ {
2
+ "type": "function",
3
+ "function": {
4
+ "name": "fetch",
5
+ "description": "Fetch HTML content from a URL.\n\n- Retrieves web page content via HTTP/HTTPS\n- Optionally extracts text-only content (strips HTML tags)\n- No user approval required\n- 30 second timeout for requests\n- Returns raw HTML or extracted text",
6
+ "parameters": {
7
+ "type": "object",
8
+ "properties": {
9
+ "url": {
10
+ "type": "string",
11
+ "description": "The URL to fetch (must be http:// or https://)"
12
+ },
13
+ "extract_text": {
14
+ "type": "boolean",
15
+ "description": "Extract only text content, removing HTML tags. Default: false",
16
+ "default": false
17
+ }
18
+ },
19
+ "required": ["url"]
20
+ }
21
+ }
22
+ }
@@ -0,0 +1,22 @@
1
+ {
2
+ "type": "function",
3
+ "function": {
4
+ "name": "web_search",
5
+ "description": "Search the web for information and return relevant links.\n\n- Primary provider: DuckDuckGo Instant Answer API (free, no API key needed)\n- Fallback provider: Brave Search API (optional, for better results if BRAVE_API_KEY is set)\n- Verifies each link exists before returning (HEAD request)\n- Returns title, URL, and snippet for each result\n- Filters out dead or inaccessible links\n- Requires user approval before making web requests\n- No CAPTCHA issues with API-based providers",
6
+ "parameters": {
7
+ "type": "object",
8
+ "properties": {
9
+ "query": {
10
+ "type": "string",
11
+ "description": "The search query to look up on the web"
12
+ },
13
+ "max_results": {
14
+ "type": "integer",
15
+ "description": "Maximum number of verified results to return. Default: 5",
16
+ "default": 5
17
+ }
18
+ },
19
+ "required": ["query"]
20
+ }
21
+ }
22
+ }
data/docs/images/demo.png CHANGED
Binary file