{"id":44861979,"url":"https://github.com/patrols/ruby_llm-text","last_synced_at":"2026-02-22T15:01:57.470Z","repository":{"id":338920676,"uuid":"1158842327","full_name":"patrols/ruby_llm-text","owner":"patrols","description":"ActiveSupport-style Ruby gem for LLM text operations: summarize, translate, extract, classify, fix grammar, sentiment analysis, and more with intuitive one-liner methods","archived":false,"fork":false,"pushed_at":"2026-02-17T13:45:41.000Z","size":30,"stargazers_count":2,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-02-18T13:58:40.525Z","etag":null,"topics":["ai","anthropic","claude","gem","gemini","llm","nlp","openai","rails","ruby","text-processing"],"latest_commit_sha":null,"homepage":"","language":"Ruby","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/patrols.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-02-16T01:31:04.000Z","updated_at":"2026-02-17T15:45:06.000Z","dependencies_parsed_at":"2026-02-17T10:02:01.441Z","dependency_job_id":null,"html_url":"https://github.com/patrols/ruby_llm-text","commit_stats":null,"previous_names":["patrols/ruby_llm-text"],"tags_count":2,"template":false,"template_full_name":null,"purl":"pkg:github/patrols/ruby_llm-text","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/patrols%2Fruby_llm-text","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/patrols%2Fruby_llm-text/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/patrols%2Fruby_llm-text/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/patrols%2Fruby_llm-text/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/patrols","download_url":"https://codeload.github.com/patrols/ruby_llm-text/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/patrols%2Fruby_llm-text/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":29612508,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-02-19T10:52:55.328Z","status":"ssl_error","status_checked_at":"2026-02-19T10:52:26.323Z","response_time":117,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.6:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["ai","anthropic","claude","gem","gemini","llm","nlp","openai","rails","ruby","text-processing"],"created_at":"2026-02-17T10:27:50.717Z","updated_at":"2026-02-19T12:01:32.121Z","avatar_url":"https://github.com/patrols.png","language":"Ruby","funding_links":[],"categories":[],"sub_categories":[],"readme":"# ruby_llm-text\n\nActiveSupport-style LLM utilities for Ruby that make AI operations feel like native Ruby.\n\n[![Gem Version](https://badge.fury.io/rb/ruby_llm-text.svg)](https://badge.fury.io/rb/ruby_llm-text)\n[![CI](https://github.com/patrols/ruby_llm-text/workflows/CI/badge.svg)](https://github.com/patrols/ruby_llm-text/actions)\n\n## Overview\n\n`ruby_llm-text` provides intuitive one-liner utility methods for common LLM tasks like summarizing text, translation, data extraction, and classification. It integrates seamlessly with the [ruby_llm](https://github.com/crmne/ruby_llm) ecosystem, providing a simple interface without requiring chat objects, message arrays, or configuration boilerplate.\n\n## Installation\n\nAdd this line to your application's Gemfile:\n\n```ruby\ngem 'ruby_llm-text'\n```\n\nAnd then execute:\n\n```bash\n$ bundle install\n```\n\nOr install it yourself as:\n\n```bash\n$ gem install ruby_llm-text\n```\n\n## Quick Start\n\n```ruby\nrequire 'ruby_llm/text'\n\n# Configure ruby_llm with your API key\nRubyLLM.configure do |config|\n  config.openai_api_key = ENV[\"OPENAI_API_KEY\"]\nend\n\n# Summarize text\nlong_article = \"This is a very long article about...\"\nsummary = RubyLLM::Text.summarize(long_article)\n\n# Translate text\ngreeting = RubyLLM::Text.translate(\"Bonjour le monde\", to: \"en\")\n\n# Extract structured data\ntext = \"My name is John and I am 30 years old.\"\ndata = RubyLLM::Text.extract(text, schema: { name: :string, age: :integer })\n\n# Classify text\nreview = \"This product is amazing!\"\nsentiment = RubyLLM::Text.classify(review, categories: [\"positive\", \"negative\", \"neutral\"])\n```\n\n## API Reference\n\n### Summarize\n\nCondense text into a shorter summary.\n\n```ruby\nRubyLLM::Text.summarize(text, length: :medium, max_words: nil, model: nil)\n```\n\n**Parameters:**\n- `text` (String): The text to summarize\n- `length` (Symbol|String): Predefined length (`:short`, `:medium`, `:detailed`) or custom description\n- `max_words` (Integer, optional): Maximum word count for summary\n- `model` (String, optional): Specific model to use\n\n**Examples:**\n```ruby\n# Basic usage\nRubyLLM::Text.summarize(\"Long article text...\")\n\n# With length option\nRubyLLM::Text.summarize(text, length: :short)\n\n# With word limit\nRubyLLM::Text.summarize(text, length: :medium, max_words: 50)\n\n# Custom length description\nRubyLLM::Text.summarize(text, length: \"bullet points\")\n```\n\n### Translate\n\nTranslate text between languages.\n\n```ruby\nRubyLLM::Text.translate(text, to:, from: nil, model: nil)\n```\n\n**Parameters:**\n- `text` (String): The text to translate\n- `to` (String): Target language (e.g., \"en\", \"spanish\", \"français\")\n- `from` (String, optional): Source language for better accuracy\n- `model` (String, optional): Specific model to use\n\n**Examples:**\n```ruby\n# Basic translation\nRubyLLM::Text.translate(\"Bonjour\", to: \"en\")\n\n# With source language specified\nRubyLLM::Text.translate(\"Hola mundo\", to: \"en\", from: \"es\")\n\n# Natural language specifications\nRubyLLM::Text.translate(\"Hello\", to: \"french\")\n```\n\n### Extract\n\nExtract structured data from unstructured text.\n\n```ruby\nRubyLLM::Text.extract(text, schema:, model: nil)\n```\n\n**Parameters:**\n- `text` (String): The text to extract data from\n- `schema` (Hash): Data structure specification\n- `model` (String, optional): Specific model to use\n\n**Schema Types:**\n- `:string` - Text fields\n- `:integer`, `:number` - Numeric fields\n- `:boolean` - True/false fields\n- `:array` - List fields\n\n**Examples:**\n```ruby\n# Extract person details\ntext = \"John Smith is 30 years old and works as a software engineer in San Francisco.\"\nschema = {\n  name: :string,\n  age: :integer,\n  profession: :string,\n  location: :string\n}\ndata = RubyLLM::Text.extract(text, schema: schema)\n\n# Extract product information\nproduct_text = \"iPhone 15 Pro costs $999 and has excellent reviews\"\nproduct_schema = {\n  name: :string,\n  price: :number,\n  currency: :string,\n  reviews: :array\n}\nproduct_data = RubyLLM::Text.extract(product_text, schema: product_schema)\n```\n\n### Classify\n\nClassify text into predefined categories.\n\n```ruby\nRubyLLM::Text.classify(text, categories:, model: nil)\n```\n\n**Parameters:**\n- `text` (String): The text to classify\n- `categories` (Array): List of possible categories\n- `model` (String, optional): Specific model to use\n\n**Examples:**\n```ruby\n# Sentiment analysis\nreview = \"This product exceeded my expectations!\"\nsentiment = RubyLLM::Text.classify(review,\n  categories: [\"positive\", \"negative\", \"neutral\"]\n)\n\n# Topic classification\narticle = \"The stock market reached new highs today...\"\ntopic = RubyLLM::Text.classify(article,\n  categories: [\"technology\", \"finance\", \"sports\", \"politics\"]\n)\n\n# Priority classification\nemail = \"URGENT: Server is down and customers can't access the site\"\npriority = RubyLLM::Text.classify(email,\n  categories: [\"low\", \"medium\", \"high\", \"critical\"]\n)\n```\n\n## Configuration\n\nThis gem uses `ruby_llm`'s configuration for API keys and default models:\n\n```ruby\n# Configure ruby_llm (API keys, default model, etc.)\nRubyLLM.configure do |config|\n  config.openai_api_key = ENV[\"OPENAI_API_KEY\"]\n  config.anthropic_api_key = ENV[\"ANTHROPIC_API_KEY\"]\n  config.default_model = \"gpt-4.1-mini\"\nend\n```\n\nOptionally configure text-specific settings:\n\n```ruby\nRubyLLM::Text.configure do |config|\n  # Temperature for text operations (default: 0.3)\n  config.temperature = 0.3\n\n  # Method-specific model overrides (falls back to RubyLLM.config.default_model)\n  config.summarize_model = \"gpt-4.1-mini\"\n  config.translate_model = \"claude-sonnet-4-5\"  # Use Claude for translation\n  config.extract_model = \"gpt-4.1\"              # Use GPT-4 for extraction\n  config.classify_model = \"gpt-4.1-mini\"\nend\n```\n\n**Per-call overrides:**\n```ruby\n# Override model for specific calls\nRubyLLM::Text.summarize(text, model: \"claude-sonnet-4-5\")\n\n# Pass additional options (passed through to ruby_llm)\nRubyLLM::Text.translate(text, to: \"es\", temperature: 0.1)\n```\n\n## String Extensions (Optional)\n\nFor a more Rails-like experience, you can enable String monkey-patching:\n\n```ruby\nrequire 'ruby_llm/text/string_ext'\n\n# Now you can call methods directly on strings\n\"Long article text...\".summarize\n\"Bonjour\".translate(to: \"en\")\n\"John is 30\".extract(schema: { name: :string, age: :integer })\n\"Great product!\".classify(categories: [\"positive\", \"negative\"])\n```\n\n## Integration with ruby_llm\n\nThis gem builds on top of [ruby_llm](https://github.com/crmne/ruby_llm) and inherits its configuration and model support:\n\n- **Models**: Supports all ruby_llm models (OpenAI GPT, Anthropic Claude, etc.)\n- **Configuration**: Uses ruby_llm's underlying configuration system\n- **Error handling**: Inherits ruby_llm's robust error handling\n\n## Error Handling\n\nThe gem provides clear error messages for common issues:\n\n```ruby\n# Missing required parameters\nRubyLLM::Text.extract(\"text\")  # ArgumentError: schema is required\n\nRubyLLM::Text.classify(\"text\", categories: [])  # ArgumentError: categories are required\n\n# API errors are wrapped with context\nRubyLLM::Text.summarize(\"text\")  # RubyLLM::Text::Error: LLM call failed: [original error]\n```\n\n## Development\n\nAfter checking out the repo, run:\n\n```bash\nbin/setup      # Install dependencies\nrake test      # Run tests\nrake rubocop   # Run linter\nrake           # Run tests and linter\n```\n\n## Testing\n\nThe test suite uses Mocha for mocking LLM API calls, ensuring reliable and fast tests without requiring API keys:\n\n```bash\n# Run all tests\nbundle exec rake test\n\n# Run tests with linting\nbundle exec rake\n\n# Run linting only\nbundle exec rubocop\n```\n\n### Manual Testing\n\nFor manual testing with real API calls, use the provided test script:\n\n```bash\n# Set up your API key\nexport OPENAI_API_KEY=\"your-key\"\n# or\nexport ANTHROPIC_API_KEY=\"your-key\"\n\n# Run manual tests\nbin/manual-test\n```\n\nThis script tests all four methods with real LLM APIs and provides helpful output for verification.\n\n## Contributing\n\nBug reports and pull requests are welcome on GitHub at https://github.com/patrols/ruby_llm-text.\n\n## License\n\nThe gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpatrols%2Fruby_llm-text","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fpatrols%2Fruby_llm-text","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpatrols%2Fruby_llm-text/lists"}