-
Notifications
You must be signed in to change notification settings - Fork 0
Add Phase 3 operations: detect_language, generate_tags, anonymize, and compare #3
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
patrols
wants to merge
9
commits into
main
Choose a base branch
from
feature/phase-3-operations
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from all commits
Commits
Show all changes
9 commits
Select commit
Hold shift + click to select a range
9191103
Add 4 new operations: detect_language, generate_tags, anonymize, compare
patrols c64f12e
Integrate new operations into existing infrastructure
patrols 0c86ba6
Add comprehensive test coverage for new operations
patrols 6adade4
Add input validation with helpful error messages
patrols 1929c47
Add AI.md
patrols b661b0d
Add documentation for Phase 3 operations
patrols 1a916f0
Bump version to 0.3.0
patrols f53aa72
Fix prompt nesting bug in compare.rb else branch
patrols 234a7cb
Fix anonymize PII handling for all styles and :all shortcut
patrols File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
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
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,124 @@ | ||
| # AI.md - Context for AI Assistants | ||
|
|
||
| ## Project Overview | ||
|
|
||
| `ruby_llm-text` is a Ruby gem that provides ActiveSupport-style LLM utilities. It offers intuitive one-liner methods for common text operations powered by LLMs, making AI operations feel like native Ruby. | ||
|
|
||
| **Repository:** https://github.com/patrols/ruby_llm-text | ||
| **License:** MIT | ||
| **Ruby:** >= 3.2.0 | ||
| **Core Dependency:** ruby_llm (~> 1.0) | ||
|
|
||
| ## Architecture | ||
|
|
||
| ### Directory Structure | ||
|
|
||
| ``` | ||
| lib/ruby_llm/ | ||
| ├── text.rb # Main module, public API entry point | ||
| └── text/ | ||
| ├── base.rb # Shared LLM calling logic & schema building | ||
| ├── configuration.rb # Text-specific configuration | ||
| ├── validation.rb # Input validation helpers | ||
| ├── string_ext.rb # Optional String monkey-patching | ||
| └── [operation].rb # Individual operation modules | ||
| ``` | ||
|
|
||
| ### Operation Pattern | ||
|
|
||
| Each operation follows a consistent pattern: | ||
|
|
||
| 1. Module under `RubyLLM::Text::[OperationName]` | ||
| 2. Class method `self.call(text, **options)` as entry point | ||
| 3. Uses `Validation.validate_text!` for input validation | ||
| 4. Calls `Base.call_llm(prompt, model:, **options)` to execute | ||
| 5. Returns processed result (string, hash, or array depending on operation) | ||
|
|
||
| Example operation file structure: | ||
| ```ruby | ||
| module RubyLLM::Text::[OperationName] | ||
| def self.call(text, **options) | ||
| Validation.validate_text!(text) | ||
| model ||= RubyLLM::Text.config.model_for(:operation_name) | ||
| prompt = build_prompt(text, **options) | ||
| Base.call_llm(prompt, model: model, **options) | ||
| end | ||
|
|
||
| def self.build_prompt(text, **options) | ||
| # Build LLM prompt | ||
| end | ||
| end | ||
| ``` | ||
|
|
||
| ### Available Operations | ||
|
|
||
| | Method | Description | | ||
| |--------|-------------| | ||
| | `summarize` | Condense text to shorter summary | | ||
| | `translate` | Translate between languages | | ||
| | `extract` | Extract structured data from text | | ||
| | `classify` | Classify into predefined categories | | ||
| | `fix_grammar` | Correct grammar/spelling errors | | ||
| | `sentiment` | Analyze sentiment with confidence | | ||
| | `key_points` | Extract main points | | ||
| | `rewrite` | Transform tone and style | | ||
| | `answer` | Answer questions about text | | ||
| | `detect_language` | Identify text language | | ||
| | `generate_tags` | Generate relevant tags | | ||
| | `anonymize` | Remove/mask PII | | ||
| | `compare` | Compare two texts | | ||
|
|
||
| ## Development | ||
|
|
||
| ### Running Tests | ||
|
|
||
| ```bash | ||
| bundle exec rake test # Run all tests | ||
| bundle exec rake rubocop # Run linter | ||
| bundle exec rake # Run both | ||
| ``` | ||
|
|
||
| ### Test Pattern | ||
|
|
||
| Tests use Minitest with Mocha for mocking. Each operation has a corresponding `test/ruby_llm/text/[operation]_test.rb` file. Tests mock the LLM responses using: | ||
|
|
||
| ```ruby | ||
| mock_chat = mock("chat") | ||
| mock_response = mock("response") | ||
| RubyLLM.expects(:chat).returns(mock_chat) | ||
| mock_chat.stubs(:with_temperature).returns(mock_chat) | ||
| mock_chat.expects(:ask).returns(mock_response) | ||
| mock_response.expects(:content).returns("mocked response") | ||
| ``` | ||
|
|
||
| ### Adding a New Operation | ||
|
|
||
| 1. Create `lib/ruby_llm/text/[operation].rb` following the operation pattern | ||
| 2. Add `require_relative "text/[operation]"` to `lib/ruby_llm/text.rb` | ||
| 3. Add module method in `RubyLLM::Text` class methods section | ||
| 4. Add tests in `test/ruby_llm/text/[operation]_test.rb` | ||
| 5. Update `lib/ruby_llm/text/string_ext.rb` if String extension desired | ||
| 6. Document in README.md | ||
|
|
||
| ### Configuration | ||
|
|
||
| Operations can be configured globally or per-call: | ||
|
|
||
| ```ruby | ||
| # Global configuration | ||
| RubyLLM::Text.configure do |config| | ||
| config.temperature = 0.3 | ||
| config.summarize_model = "gpt-4.1-mini" | ||
| end | ||
|
|
||
| # Per-call override | ||
| RubyLLM::Text.summarize(text, model: "claude-sonnet-4-5") | ||
| ``` | ||
|
|
||
| ## Code Style | ||
|
|
||
| - Follow rubocop-rails-omakase conventions | ||
| - Keep operations focused and single-purpose | ||
| - Use keyword arguments for options | ||
| - Validate inputs early with helpful error messages | ||
| - Return clean data (strings, hashes, arrays) - not raw LLM response objects |
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
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
Oops, something went wrong.
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.
Uh oh!
There was an error while loading. Please reload this page.