ollama_agent 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.
Files changed (37) hide show
  1. checksums.yaml +7 -0
  2. data/.cursor/.gitignore +1 -0
  3. data/.cursor/skills/ollama-agent-patterns/SKILL.md +132 -0
  4. data/.cursor/skills/ollama-agent-patterns/reference.md +428 -0
  5. data/.env.example +27 -0
  6. data/CHANGELOG.md +5 -0
  7. data/CODE_OF_CONDUCT.md +10 -0
  8. data/LICENSE.txt +21 -0
  9. data/README.md +147 -0
  10. data/Rakefile +12 -0
  11. data/exe/ollama_agent +13 -0
  12. data/lib/ollama_agent/agent.rb +146 -0
  13. data/lib/ollama_agent/agent_prompt.rb +44 -0
  14. data/lib/ollama_agent/cli.rb +73 -0
  15. data/lib/ollama_agent/console.rb +136 -0
  16. data/lib/ollama_agent/diff_path_validator.rb +141 -0
  17. data/lib/ollama_agent/ollama_connection.rb +14 -0
  18. data/lib/ollama_agent/patch_support.rb +78 -0
  19. data/lib/ollama_agent/repo_list.rb +50 -0
  20. data/lib/ollama_agent/ruby_index/builder.rb +115 -0
  21. data/lib/ollama_agent/ruby_index/extractor_visitor.rb +81 -0
  22. data/lib/ollama_agent/ruby_index/formatter.rb +65 -0
  23. data/lib/ollama_agent/ruby_index/index.rb +51 -0
  24. data/lib/ollama_agent/ruby_index/naming.rb +27 -0
  25. data/lib/ollama_agent/ruby_index.rb +17 -0
  26. data/lib/ollama_agent/ruby_index_tool_support.rb +52 -0
  27. data/lib/ollama_agent/ruby_search_modes.rb +9 -0
  28. data/lib/ollama_agent/sandboxed_tools.rb +216 -0
  29. data/lib/ollama_agent/think_param.rb +27 -0
  30. data/lib/ollama_agent/timeout_param.rb +20 -0
  31. data/lib/ollama_agent/tool_arguments.rb +26 -0
  32. data/lib/ollama_agent/tool_content_parser.rb +44 -0
  33. data/lib/ollama_agent/tools_schema.rb +78 -0
  34. data/lib/ollama_agent/version.rb +5 -0
  35. data/lib/ollama_agent.rb +11 -0
  36. data/sig/ollama_agent.rbs +4 -0
  37. metadata +182 -0
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 73ed8cb32bcabdd008dee785606c96aefc9bf626a3c3a1187b7bab8ef68c9627
4
+ data.tar.gz: 150f32efcba0bd8602cd571654bcfc8f42b99af56873a57d792202bb957b4701
5
+ SHA512:
6
+ metadata.gz: 18ce5ec435f2b8330e2684dd116bd33b9e399d93857a5469365902a19a3f99b61bf7d227df746b5bbe82d7b77c4f952b3e2ad8ac61b204498e4d07f469978de0
7
+ data.tar.gz: fd59f660457f2de80e949a098283b38eeccb94cb9daa757158d76d3f457a1f0926ef30f5f5e98ba864ef7504470842775c971ed0a373f48ba8e26b6b0ecdc129
@@ -0,0 +1 @@
1
+ plans/
@@ -0,0 +1,132 @@
1
+ ---
2
+ name: ollama-agent-patterns
3
+ description: >-
4
+ Blueprint for building a CLI Ollama-based coding agent (Ruby gem) with design
5
+ patterns and judicious metaprogramming—Facade, Template Method, Factory/Registry,
6
+ Builder, Adapter, Proxy, Command, Observer, Strategy, State, and tool DSLs. Use
7
+ when working on ollama_agent, ollama-client integration, tools, LLM adapters,
8
+ prompts, streaming, patch application, or when the user asks for agent
9
+ architecture, extensibility, registries, or Ruby metaprogramming for agents.
10
+ ---
11
+
12
+ # Skill: Ollama Agent — Design Patterns & Metaprogramming
13
+
14
+ ## 1. Overview
15
+
16
+ Blueprint for a **CLI coding agent** (e.g. `ollama_agent`) that uses **ollama-client** to chat with tools: read/search files, apply small unified diffs from natural language. Patterns keep the design **extensible and maintainable** without front-loading complexity.
17
+
18
+ ## 2. Core components & patterns
19
+
20
+ | Component | Pattern(s) | Purpose |
21
+ |-----------|------------|---------|
22
+ | **Agent** | Facade, Template Method | Simple API (`run`); skeleton loop with overridable steps. |
23
+ | **Tools** | Factory Method, Command, Registry | Load/execute tools; optional logging/replay/undo. |
24
+ | **LLM client** | Adapter, (optional) Proxy | Swap backends; logging/metrics without forking core. |
25
+ | **Prompts** | Builder | Fluent construction of messages + tools + options. |
26
+ | **Streaming** | Observer | Multiple subscribers for tokens (UI, logs). |
27
+ | **Patch application** | Strategy | Swap `patch(1)` vs Ruby-native apply, etc. |
28
+ | **Conversation** | State | Phases (idle, tools, confirmation) without giant `if/else`. |
29
+
30
+ **Client lifetime:** **Singleton** is optional. Prefer **injectable** `Ollama::Client` (or adapter) for tests and per-run config (`timeout`, `base_url`, `api_key`).
31
+
32
+ ## 3. Principles
33
+
34
+ 1. **Start simple** — add Factory, State, Strategy when duplication or branching hurts; do not adopt every pattern up front.
35
+ 2. **Core loop stays explicit** — readable `run` / tool loop; collaborators (`Adapter`, `PromptBuilder`, `ToolCommand`) hide detail, not `send` spaghetti.
36
+ 3. **Metaprogramming at boundaries** — registration / DSLs at tool edges; avoid dynamic dispatch in error paths and hot loops unless measured.
37
+ 4. **Workspace rules** — validated tool schemas; loggable/replayable actions; **no hardcoded model names** (runtime config).
38
+
39
+ ## 4. Pattern map (where code lives)
40
+
41
+ | Area | Patterns | Role |
42
+ |------|-----------|------|
43
+ | **Agent** | Facade, Template Method | Single entry; fixed loop with overridable hooks. |
44
+ | **Tools** | Factory, Command, Registry | Instantiate tools; optional command objects for audit. |
45
+ | **LLM** | Adapter, Proxy | Backends; cross-cutting logging/rate limits. |
46
+ | **Prompts** | Builder | Messages + tools + options. |
47
+ | **Streaming** | Observer | Fan-out from client `hooks`. |
48
+ | **Patches** | Strategy | Pluggable apply path. |
49
+ | **Conversation** | State | Explicit phases when control flow grows. |
50
+
51
+ ### Target layout (illustrative)
52
+
53
+ A fuller **pattern-oriented** tree (with `bin/console`, `commands/`, `strategies/`, `states/`, etc.) and a **“this repo today”** note live in **reference.md** under *Recommended gem structure*. Migrate only when complexity justifies new directories.
54
+
55
+ ```
56
+ ollama_agent/
57
+ ├── exe/ollama_agent
58
+ ├── lib/ollama_agent.rb
59
+ └── lib/ollama_agent/
60
+ ├── agent.rb
61
+ ├── cli.rb
62
+ ├── prompt_builder.rb # Builder (optional)
63
+ ├── tool_registry.rb
64
+ ├── tools/base.rb
65
+ ├── tools/
66
+ ├── llm/base_adapter.rb
67
+ ├── llm/ollama_adapter.rb
68
+ ├── llm/logging_proxy.rb
69
+ ├── commands/tool_command.rb
70
+ ├── observers/
71
+ ├── strategies/
72
+ └── states/
73
+ ```
74
+
75
+ ## 5. Creational patterns (summary)
76
+
77
+ - **Factory + registry** — Replace a growing `case` with `ToolRegistry.get(name)`; auto-register via `inherited` **or** explicit `tool_name` + hash (clearer than magic naming).
78
+ - **Builder** — `PromptBuilder` when message construction branches; skip until you have real optional composition.
79
+ - **Singleton** — Avoid as default for HTTP clients; use when you truly need one process-wide resource and tests can still stub.
80
+
81
+ ## 6. Structural patterns (summary)
82
+
83
+ - **Adapter** — Common `chat(messages:, tools:, **options)` surface for Ollama vs future providers.
84
+ - **Proxy** — Wrap adapter for logging/metrics; keep thin.
85
+ - **Facade** — `Agent#run` — already the right shape.
86
+
87
+ ## 7. Behavioral patterns (summary)
88
+
89
+ - **Command** — Wrap tool invocations when you need queues, structured logs, or replay; **undo** only with a real story (VCS/snapshots).
90
+ - **Observer** — Fan-out streaming tokens; compose with ollama-client `hooks`.
91
+ - **Strategy** — `PatchStrategy` if you need non-`patch` apply paths.
92
+ - **State** — When confirmation + tool rounds + idle become tangled.
93
+ - **Template Method** — Base agent class only if you have **multiple** agent variants sharing one loop.
94
+
95
+ ## 8. Metaprogramming (judicious)
96
+
97
+ | Technique | Use when | Caution |
98
+ |-----------|----------|--------|
99
+ | **`inherited` + registry** | Many tools, stable naming | Keep in sync with **tool JSON schema**; consider explicit `tool_name`. |
100
+ | **Tool DSL** (`tool :name do …`) | Repetition dominates | Stack traces and IDE nav suffer; keep DSL thin. |
101
+ | **`send` for hooks** | Fixed event names | Prefer explicit methods for public API. |
102
+ | **`method_missing`** | Rare delegation | Not for core tool dispatch — use a Hash/registry. |
103
+ | **Plugin `extend`** | Third-party tools | Document load order and sandbox rules. |
104
+
105
+ ## 9. When to avoid heavy metaprogramming
106
+
107
+ - Main agent loop and **error handling** — explicit flow wins.
108
+ - **Performance-sensitive** inner loops — measure before dynamic dispatch.
109
+ - **Public APIs** — stable, documented entry points over hidden DSL magic.
110
+
111
+ ## 10. Summary
112
+
113
+ | Pattern | Benefit |
114
+ |---------|---------|
115
+ | Factory Method | Decouples tool creation from call sites. |
116
+ | Builder | Composes prompts/options without positional arg soup. |
117
+ | Singleton | Single shared resource (use sparingly for HTTP clients). |
118
+ | Adapter | Multiple LLM backends behind one shape. |
119
+ | Proxy | Cross-cutting concerns on the client. |
120
+ | Facade | Hides orchestration from CLI users. |
121
+ | Command | Tool calls as objects (log/replay/queue). |
122
+ | Observer | Decoupled streaming consumers. |
123
+ | Strategy | Swappable patch application. |
124
+ | State | Explicit conversation phases. |
125
+ | Template Method | Shared loop, varied steps. |
126
+ | Metaprogramming | Less boilerplate at **boundaries** only. |
127
+
128
+ **Start with straightforward code; refactor into patterns when pain appears.**
129
+
130
+ ## 11. Full code examples
131
+
132
+ Runnable snippets (registry, `PromptBuilder`, adapters, proxy, command, observer, strategy, state, template-method skeleton, DSL sketch) live in **[reference.md](reference.md)**. Prefer copying from there and adapting to the real `ollama-client` API and this repo’s `SandboxedTools` / `tools_schema` constraints.
@@ -0,0 +1,428 @@
1
+ # Reference: patterns & Ruby snippets
2
+
3
+ Concise examples for `ollama_agent`-style gems. Adapt names to the real `ollama-client` API.
4
+
5
+ ## Factory Method + registry (`inherited`)
6
+
7
+ ```ruby
8
+ # lib/ollama_agent/tools/base.rb
9
+ module OllamaAgent
10
+ module Tools
11
+ class Base
12
+ def initialize(args)
13
+ @args = args
14
+ end
15
+
16
+ def call
17
+ raise NotImplementedError
18
+ end
19
+
20
+ def self.inherited(subclass)
21
+ return if subclass.name.nil?
22
+
23
+ name = subclass.name.split("::").last.underscore
24
+ ToolRegistry.register(name, subclass)
25
+ end
26
+ end
27
+ end
28
+ end
29
+
30
+ # lib/ollama_agent/tools/registry.rb — or tool_registry.rb at module root
31
+ module OllamaAgent
32
+ module Tools
33
+ class ToolRegistry
34
+ @tools = {}
35
+ class << self
36
+ def register(name, klass)
37
+ @tools[name.to_s] = klass
38
+ end
39
+
40
+ def get(name)
41
+ @tools[name.to_s]
42
+ end
43
+ end
44
+ end
45
+ end
46
+ end
47
+ ```
48
+
49
+ ## Builder (`PromptBuilder`)
50
+
51
+ ```ruby
52
+ class PromptBuilder
53
+ attr_reader :messages, :tools, :options
54
+
55
+ def initialize
56
+ @messages = []
57
+ @tools = []
58
+ @options = {}
59
+ end
60
+
61
+ def system(content)
62
+ @messages << { role: "system", content: content }
63
+ self
64
+ end
65
+
66
+ def user(content)
67
+ @messages << { role: "user", content: content }
68
+ self
69
+ end
70
+
71
+ def add_tool(tool_def)
72
+ @tools << tool_def
73
+ self
74
+ end
75
+
76
+ def temperature(value)
77
+ @options[:temperature] = value
78
+ self
79
+ end
80
+
81
+ def build
82
+ { messages: @messages, tools: @tools, options: @options }
83
+ end
84
+ end
85
+ ```
86
+
87
+ ## Singleton (optional client holder)
88
+
89
+ ```ruby
90
+ require "singleton"
91
+
92
+ class OllamaClientWrapper
93
+ include Singleton
94
+
95
+ attr_reader :client
96
+
97
+ def initialize
98
+ @client = Ollama::Client.new(model: ENV.fetch("OLLAMA_MODEL"))
99
+ end
100
+ end
101
+ ```
102
+
103
+ Prefer **dependency injection** of a client/adapter in tests instead of `Singleton` when practical.
104
+
105
+ ## Adapter + Proxy
106
+
107
+ ```ruby
108
+ # lib/ollama_agent/llm/base_adapter.rb
109
+ module OllamaAgent
110
+ module LLM
111
+ class BaseAdapter
112
+ def chat(messages:, tools:, **options)
113
+ raise NotImplementedError
114
+ end
115
+ end
116
+ end
117
+ end
118
+
119
+ # lib/ollama_agent/llm/ollama_adapter.rb
120
+ module OllamaAgent
121
+ module LLM
122
+ class OllamaAdapter < BaseAdapter
123
+ def initialize(client = Ollama::Client.new)
124
+ @client = client
125
+ end
126
+
127
+ def chat(messages:, tools:, **options)
128
+ @client.chat(messages: messages, tools: tools, **options)
129
+ end
130
+ end
131
+ end
132
+ end
133
+
134
+ # lib/ollama_agent/llm/logging_proxy.rb
135
+ module OllamaAgent
136
+ module LLM
137
+ class LoggingProxy
138
+ def initialize(adapter, logger: $stderr)
139
+ @adapter = adapter
140
+ @logger = logger
141
+ end
142
+
143
+ def chat(...)
144
+ @logger.puts "LLM chat request"
145
+ @adapter.chat(...)
146
+ end
147
+ end
148
+ end
149
+ end
150
+ ```
151
+
152
+ ## Command (tool execution)
153
+
154
+ ```ruby
155
+ class ToolCommand
156
+ attr_reader :name, :args, :result
157
+
158
+ def initialize(name, args)
159
+ @name = name
160
+ @args = args
161
+ end
162
+
163
+ def execute
164
+ klass = Tools::ToolRegistry.get(@name)
165
+ raise KeyError, "Unknown tool: #{@name}" unless klass
166
+
167
+ @result = klass.new(@args).call
168
+ end
169
+
170
+ def undo
171
+ # Optional: revert file edits, etc.
172
+ end
173
+ end
174
+ ```
175
+
176
+ ## Observer (streaming)
177
+
178
+ ```ruby
179
+ class Agent
180
+ def initialize(adapter:)
181
+ @adapter = adapter
182
+ @observers = []
183
+ end
184
+
185
+ def add_observer(observer)
186
+ @observers << observer
187
+ end
188
+
189
+ def notify_observers(token, logprobs)
190
+ @observers.each { |obs| obs.update(token, logprobs) }
191
+ end
192
+ end
193
+ ```
194
+
195
+ Wire `on_token` (or equivalent) from `ollama-client` to `notify_observers`.
196
+
197
+ ## Strategy (patch application)
198
+
199
+ ```ruby
200
+ class PatchStrategy
201
+ def apply(path, diff)
202
+ raise NotImplementedError
203
+ end
204
+ end
205
+
206
+ class SystemPatchStrategy < PatchStrategy
207
+ def apply(path, diff)
208
+ IO.popen(["patch", "-p1", "-f", path.to_s], "w") { |stdin| stdin.write(diff) }
209
+ end
210
+ end
211
+ ```
212
+
213
+ ## State (conversation phases)
214
+
215
+ ```ruby
216
+ class AgentState
217
+ def handle(agent, response)
218
+ raise NotImplementedError
219
+ end
220
+ end
221
+
222
+ class IdleState < AgentState
223
+ def handle(agent, response)
224
+ # transition when tool calls appear
225
+ end
226
+ end
227
+
228
+ class ToolExecutionState < AgentState
229
+ def handle(agent, response)
230
+ # run tools, append results, return to idle
231
+ end
232
+ end
233
+ ```
234
+
235
+ ## Template Method (agent loop)
236
+
237
+ ```ruby
238
+ class BaseAgent
239
+ def run(query)
240
+ messages = build_initial_messages(query)
241
+ loop do
242
+ response = send_to_llm(messages)
243
+ if tool_calls?(response)
244
+ messages << assistant_message(response)
245
+ process_tool_calls(tool_calls(response), messages)
246
+ else
247
+ handle_final_response(response, messages)
248
+ break
249
+ end
250
+ end
251
+ end
252
+
253
+ def build_initial_messages(query)
254
+ raise NotImplementedError
255
+ end
256
+
257
+ def send_to_llm(messages)
258
+ raise NotImplementedError
259
+ end
260
+
261
+ def process_tool_calls(_tool_calls, _messages)
262
+ raise NotImplementedError
263
+ end
264
+
265
+ def handle_final_response(_response, _messages)
266
+ raise NotImplementedError
267
+ end
268
+ end
269
+ ```
270
+
271
+ ## Metaprogramming: tool DSL (optional)
272
+
273
+ ```ruby
274
+ class BaseTool
275
+ def self.tool(name, description, &block)
276
+ define_method(:call, &block)
277
+ Tools::ToolRegistry.register(name.to_s, self)
278
+ end
279
+ end
280
+ ```
281
+
282
+ Prefer explicit subclasses + `inherited` registration if the DSL obscures tests.
283
+
284
+ ## Dynamic hooks
285
+
286
+ ```ruby
287
+ def trigger_hook(event)
288
+ m = :"on_#{event}"
289
+ send(m) if respond_to?(m, true)
290
+ end
291
+ ```
292
+
293
+ ## Putting it together (illustrative)
294
+
295
+ ```ruby
296
+ module OllamaAgent
297
+ class Agent
298
+ def initialize(adapter:, tool_registry: Tools::ToolRegistry)
299
+ @adapter = adapter
300
+ @tool_registry = tool_registry
301
+ @state = IdleState.new
302
+ @observers = []
303
+ end
304
+
305
+ def run(query)
306
+ built = PromptBuilder.new
307
+ .system(SYSTEM_PROMPT)
308
+ .user(query)
309
+ .temperature(0.2)
310
+ .build
311
+
312
+ messages = built[:messages]
313
+ # Loop: @adapter.chat with messages/tools/options; @state.handle; execute tools via ToolCommand
314
+ end
315
+
316
+ def add_observer(observer)
317
+ @observers << observer
318
+ end
319
+
320
+ def execute_tool(tool_call)
321
+ klass = @tool_registry.get(tool_call.name)
322
+ raise KeyError, "Unknown tool: #{tool_call.name}" unless klass
323
+
324
+ command = ToolCommand.new(tool_call.name, tool_call.arguments)
325
+ command.execute
326
+ command.result
327
+ end
328
+ end
329
+ end
330
+ ```
331
+
332
+ ## Main entry `require` pattern
333
+
334
+ ```ruby
335
+ # lib/ollama_agent.rb
336
+ require_relative "ollama_agent/version"
337
+ require_relative "ollama_agent/tool_registry"
338
+ require_relative "ollama_agent/tools/base"
339
+ Dir[File.join(__dir__, "ollama_agent", "tools", "*.rb")].sort.each { |f| require f }
340
+ # require LLM, commands, agent, cli
341
+ ```
342
+
343
+ Skip globs if load order matters; require explicit files instead.
344
+
345
+ ---
346
+
347
+ ## Recommended gem structure (pattern-oriented layout)
348
+
349
+ Use this when growing toward explicit registries, adapters, and strategies. Omit directories you do not need yet (e.g. `states/`, `strategies/`).
350
+
351
+ ```
352
+ ollama_agent/
353
+ ├── bin/
354
+ │ └── console
355
+ ├── exe/
356
+ │ └── ollama_agent
357
+ ├── lib/
358
+ │ ├── ollama_agent.rb
359
+ │ ├── ollama_agent/
360
+ │ │ ├── version.rb
361
+ │ │ ├── cli.rb
362
+ │ │ ├── agent.rb # Facade + template-method loop
363
+ │ │ ├── prompt_builder.rb
364
+ │ │ ├── tool_registry.rb # name → class (not a process Singleton)
365
+ │ │ ├── tools/
366
+ │ │ │ ├── base.rb # inherited hook / optional DSL
367
+ │ │ │ ├── read_file.rb
368
+ │ │ │ ├── search_code.rb
369
+ │ │ │ └── edit_file.rb
370
+ │ │ ├── llm/
371
+ │ │ │ ├── base_adapter.rb
372
+ │ │ │ ├── ollama_adapter.rb
373
+ │ │ │ └── logging_proxy.rb
374
+ │ │ ├── commands/
375
+ │ │ │ └── tool_command.rb
376
+ │ │ ├── observers/
377
+ │ │ │ ├── base_observer.rb
378
+ │ │ │ └── token_observer.rb
379
+ │ │ ├── strategies/
380
+ │ │ │ ├── patch_strategy.rb
381
+ │ │ │ └── system_patch_strategy.rb
382
+ │ │ └── states/
383
+ │ │ ├── agent_state.rb
384
+ │ │ ├── idle_state.rb
385
+ │ │ └── tool_execution_state.rb
386
+ ├── spec/
387
+ └── ollama_agent.gemspec
388
+ ```
389
+
390
+ ### Where each pattern lives
391
+
392
+ | Pattern / concept | Location |
393
+ |-------------------|----------|
394
+ | Facade | `agent.rb` — `run` |
395
+ | Template method | `agent.rb` — loop skeleton; subclasses override hooks if needed |
396
+ | Builder | `prompt_builder.rb` |
397
+ | Registry | `tool_registry.rb` — map of tool names to classes |
398
+ | Factory / auto-registration | `tools/base.rb` — `inherited` (or explicit registration) |
399
+ | Adapter | `llm/base_adapter.rb`, `llm/ollama_adapter.rb` |
400
+ | Proxy | `llm/logging_proxy.rb` |
401
+ | Command | `commands/tool_command.rb` |
402
+ | Observer | `observers/` |
403
+ | Strategy | `strategies/` — patch application |
404
+ | State | `states/` — conversation phases |
405
+ | Metaprogramming / DSL | `tools/base.rb` — optional `tool` class method |
406
+
407
+ ### `lib/ollama_agent.rb` require order (example)
408
+
409
+ ```ruby
410
+ require_relative "ollama_agent/version"
411
+ require_relative "ollama_agent/cli"
412
+ require_relative "ollama_agent/agent"
413
+ require_relative "ollama_agent/prompt_builder"
414
+ require_relative "ollama_agent/tool_registry"
415
+ require_relative "ollama_agent/tools/base"
416
+ Dir[File.join(__dir__, "ollama_agent", "tools", "*.rb")].sort.each { |f| require f }
417
+ # then llm/, commands/, strategies/, etc.
418
+ ```
419
+
420
+ Prefer explicit `require_relative` per file when load order matters (subclasses after `Base`).
421
+
422
+ ### Benefits
423
+
424
+ - Separation of concerns; isolated unit tests; clear extension points for tools, strategies, observers.
425
+
426
+ ### This repository today (flatter)
427
+
428
+ The live `ollama_agent` gem currently uses a **smaller** layout: e.g. `sandboxed_tools.rb`, `tools_schema.rb`, `patch_support.rb`, `diff_path_validator.rb`, `agent_prompt.rb`, `ollama_connection.rb` — same responsibilities, fewer directories. Migrating to the tree above is optional and should follow real need (second LLM backend, multiple patch strategies, etc.).
data/.env.example ADDED
@@ -0,0 +1,27 @@
1
+ # Example environment variables for OllamaAgent gem
2
+ # Disable colored output (set to any value to respect https://no-color.org/)
3
+ NO_COLOR=
4
+ # Enable colored output (default: enabled). Set to "0" to disable.
5
+ OLLAMA_AGENT_COLOR=1
6
+ # Enable markdown rendering in terminal (default: enabled). Set to "0" to disable.
7
+ OLLAMA_AGENT_MARKDOWN=1
8
+ # Render thinking output with markdown (default: disabled). Set to "1" to enable.
9
+ OLLAMA_AGENT_THINKING_MARKDOWN=0
10
+ # Base URL for Ollama server
11
+ OLLAMA_BASE_URL=https://ollama.com
12
+ # API key for Ollama (if required)
13
+ OLLAMA_API_KEY=your_api_key_here
14
+ # Think parameter: true/false/high/medium/low (default: true)
15
+ OLLAMA_AGENT_THINK=1
16
+ # Root directory for the agent (default: current working directory)
17
+ OLLAMA_AGENT_ROOT=.
18
+ # Debug mode (set to "1" for verbose output)
19
+ OLLAMA_AGENT_DEBUG=0
20
+ # Maximum tool rounds (default: 64)
21
+ OLLAMA_AGENT_MAX_TURNS=64
22
+ # Model to use (default: from Ollama config)
23
+ OLLAMA_AGENT_MODEL=gpt-oss:120b-cloud
24
+ # HTTP timeout in seconds for Ollama requests
25
+ OLLAMA_AGENT_TIMEOUT=120
26
+ # Parse tool JSON from assistant output (set to "1" to enable)
27
+ OLLAMA_AGENT_PARSE_TOOL_JSON=0
data/CHANGELOG.md ADDED
@@ -0,0 +1,5 @@
1
+ ## [Unreleased]
2
+
3
+ ## [0.1.0] - 2026-03-21
4
+
5
+ - Initial release
@@ -0,0 +1,10 @@
1
+ # Code of Conduct
2
+
3
+ "ollama_agent" follows [The Ruby Community Conduct Guideline](https://www.ruby-lang.org/en/conduct) in all "collaborative space", which is defined as community communications channels (such as mailing lists, submitted patches, commit comments, etc.):
4
+
5
+ * Participants will be tolerant of opposing views.
6
+ * Participants must ensure that their language and actions are free of personal attacks and disparaging personal remarks.
7
+ * When interpreting the words and actions of others, participants should always assume good intentions.
8
+ * Behaviour which can be reasonably considered harassment will not be tolerated.
9
+
10
+ If you have any concerns about behaviour within this project, please contact us at ["shubhamtaywade82@gmail.com"](mailto:"shubhamtaywade82@gmail.com").
data/LICENSE.txt ADDED
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2026 Shubham Taywade
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in
13
+ all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ THE SOFTWARE.