Add agentic coding loop with tools and orchestrator#22
Open
Add agentic coding loop with tools and orchestrator#22
Conversation
Core Tools (RubyLLM::Tool subclasses): - ReadFile: read files with line numbers, offset/limit support - WriteFile: create/overwrite files, auto-create directories - EditFile: search-and-replace edits with uniqueness validation - BashExec: shell execution with safety blocklist and output truncation - ListFiles: glob-based file search - Grep: ripgrep/grep wrapper for content search Agent (Level 1 — single LLM turn with tool calls): - Wraps persistent RubyLLM chat with all tools registered - System prompt for coding assistant behavior - Tool call/result callbacks for real-time visibility - Tracks modified files across tool calls - step/ask/add_context/next_step interface for Orchestrator Orchestrator (Level 2 — multi-turn task completion): - Manages multiple Agent turns toward a goal - Auto-detects project type (Ruby/Rust/Node/Python) - Runs validation (tests/lint) between LLM turns - Feeds failures back to Agent for self-correction - Iteration limits with user confirmation to continue - Event-based callback for TUI integration CLI Integration: - /code TASK command runs the full agentic loop - Real-time tool call display during execution - --max-iterations and --profile flags - Works in both CLI and TUI modes Specs: 377 total (39 new), 0 failures - Tool specs: ReadFile, WriteFile, EditFile, BashExec, ListFiles - Agent: initialization, step, context, reset - Orchestrator: completion detection, iteration limits, project detection Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Add section 3 covering /code command, agent loop architecture (Level 1 tool calls + Level 2 orchestrator), available tools, and auto-validation. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Rewrite exe/ragnar to detect command position and reorder args so
global options (--profile) work before or after the command name
- Remove default_command :interactive (handled by executable instead)
- Add exit_on_failure? to suppress Thor deprecation warning
- Both work now: ragnar --profile opus code "task"
ragnar code --profile opus "task"
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Instead of string-matching "I've completed" in LLM responses (fragile, caused 6 unnecessary iterations), the agent now signals completion by calling the TaskComplete tool. RubyLLM's halt mechanism stops the tool loop immediately and returns the summary. New tools: - TaskComplete: agent calls when task is done, with summary - AskUser: agent calls when it needs user clarification Orchestrator changes: - detect_signal reads last tool call instead of parsing prose - Loop structure: check signal first, then decide next action - Validation still runs on task_complete if files were modified System prompt updated to instruct the LLM to use these tools. 387 specs, 0 failures (6 new tool/orchestrator specs) Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Enable bundler-cache in ruby/setup-ruby (caches compiled native extensions for red-candle, clusterkit, lancelot) - Add restore-keys for cargo cache (partial hits still save time) - Remove manual bundle install (handled by bundler-cache) Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Ragnar is no longer just a RAG pipeline — it's a hackable, Claude Code-style coding agent. The README now leads with that identity: - New tagline: "An agentic coding assistant for Ruby" - Architecture section: two-level loop diagram (Orchestrator + Agent) - Tools table with all 8 tools - "How It Works" section for developers: key files, line counts, design decisions - Quick Start leads with /code (agentic mode), not indexing - RAG is presented as one capability, not the whole product - Built With table replaces scattered acknowledgments - Removed outdated sections (performance benchmarks, optimization tips, detailed topic modeling examples) Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Orchestrator: expanded class comment explaining Level 1 vs Level 2 and
why the orchestrator exists ("chatbot with tools" vs "coding assistant")
- Agent: explains what happens inside chat.ask(), why history persists,
and how the tool call log connects to the Orchestrator
- TaskComplete: documents the journey from string matching to tool-based
signaling, and why this pattern is used in production agents
- BashExec: explains the three-part tool pattern (description, params, execute)
and how RubyLLM converts it to JSON Schema automatically
- tools.rb: explains how to add new tools
- README: "designed to be read, understood, and extended" (not "to learn from")
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Adds a Claude Code-style agentic coding assistant to ragnar. The agent can read files, write code, run commands, and self-correct — all orchestrated by a two-level loop architecture designed to be readable and hackable by Ruby developers.
Architecture: Two Levels of Looping
Level 1 — Tool execution (RubyLLM handles this)
The LLM makes tool calls within a single turn. RubyLLM automatically executes tools, feeds results back, and loops until the LLM produces a final response.
Level 2 — Task orchestration (
Orchestrator)The "brain outside the brain" manages multiple LLM turns:
Tools (8
RubyLLM::Toolsubclasses)ReadFileWriteFileEditFileBashExecListFilesGrepTaskCompletehalt)AskUserhalt)Key Design Decisions
TaskCompletetool instead of string matching — The agent explicitly signals completion by calling a tool, not by saying "I'm done" in prose. RubyLLM'shaltmechanism stops the loop immediately. This eliminated a bug where the orchestrator looped 6 times after the agent was already done.AskUsertool for user interaction — Same pattern: the agent calls a tool to pause and ask the user, rather than the orchestrator parsing the response for questions.CLI
Files
lib/ragnar/tools/— 8 tool classes (~310 lines)lib/ragnar/agent.rb— Agent with persistent chat + tools (114 lines)lib/ragnar/orchestrator.rb— Level 2 loop (163 lines)exe/ragnar— Fixed arg ordering for--profilebefore commandTest plan
ragnar --profile opus code "Create fizzbuzz.rb in /tmp and run it"— completes in 1 iterationrm -rf /,shutdown)🤖 Generated with Claude Code