ruby_llm-text 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.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: bb717f8d64403316c14b7da6ae2354f5f72d60a2caae6c892ca3f9fe109343d8
4
+ data.tar.gz: 286d134ed832cee3a0289052b5b81693a6b70822080dc9f4fa3535c492f73198
5
+ SHA512:
6
+ metadata.gz: 7227c8ae62491a00d308d3d59751435f404d5ee1e405b71db323a3b4edab832dac23bbc7162ef530562bae28d58ef5a765ba89f790d0f4e07469b99964519873
7
+ data.tar.gz: bb9eea87d7aafb8251a49ea5137f073fc5eea5a0ffcf29a699c2251bde7cfd31131afb81d51f293befa5faba8e1f397ca0080cd0626f6c394db4fcd2729a5f25
data/CHANGELOG.md ADDED
@@ -0,0 +1,31 @@
1
+ # Changelog
2
+
3
+ All notable changes to this project will be documented in this file.
4
+
5
+ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
6
+ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
+
8
+ ## [Unreleased]
9
+
10
+ ## [0.1.0] - 2025-02-16
11
+
12
+ ### Added
13
+ - Initial release of ruby_llm-text gem
14
+ - Core functionality for LLM text operations:
15
+ - `summarize` - Condense text into shorter summaries with configurable length
16
+ - `translate` - Translate text between languages
17
+ - `extract` - Extract structured data from unstructured text using schemas
18
+ - `classify` - Classify text into predefined categories
19
+ - Configuration system with per-method model overrides
20
+ - String extensions for Rails-like method chaining (optional)
21
+ - Integration with ruby_llm ecosystem
22
+ - Comprehensive test suite with 100% coverage
23
+ - GitHub Actions CI/CD pipeline
24
+ - Complete documentation and API reference
25
+
26
+ ### Dependencies
27
+ - ruby_llm ~> 1.0 (core dependency)
28
+ - Ruby >= 3.2.0
29
+
30
+ [Unreleased]: https://github.com/patrols/ruby_llm-text/compare/v0.1.0...HEAD
31
+ [0.1.0]: https://github.com/patrols/ruby_llm-text/releases/tag/v0.1.0
data/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 Patrick Rendal Olsen
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 all
13
+ 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 THE
21
+ SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,312 @@
1
+ # ruby_llm-text
2
+
3
+ ActiveSupport-style LLM utilities for Ruby that make AI operations feel like native Ruby.
4
+
5
+ [![Gem Version](https://badge.fury.io/rb/ruby_llm-text.svg)](https://badge.fury.io/rb/ruby_llm-text)
6
+ [![CI](https://github.com/patrols/ruby_llm-text/workflows/CI/badge.svg)](https://github.com/patrols/ruby_llm-text/actions)
7
+
8
+ ## Overview
9
+
10
+ `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.
11
+
12
+ ## Installation
13
+
14
+ Add this line to your application's Gemfile:
15
+
16
+ ```ruby
17
+ gem 'ruby_llm-text'
18
+ ```
19
+
20
+ And then execute:
21
+
22
+ ```bash
23
+ $ bundle install
24
+ ```
25
+
26
+ Or install it yourself as:
27
+
28
+ ```bash
29
+ $ gem install ruby_llm-text
30
+ ```
31
+
32
+ ## Quick Start
33
+
34
+ ```ruby
35
+ require 'ruby_llm/text'
36
+
37
+ # Configure ruby_llm with your API key
38
+ RubyLLM.configure do |config|
39
+ config.openai_api_key = ENV["OPENAI_API_KEY"]
40
+ end
41
+
42
+ # Summarize text
43
+ long_article = "This is a very long article about..."
44
+ summary = RubyLLM::Text.summarize(long_article)
45
+
46
+ # Translate text
47
+ greeting = RubyLLM::Text.translate("Bonjour le monde", to: "en")
48
+
49
+ # Extract structured data
50
+ text = "My name is John and I am 30 years old."
51
+ data = RubyLLM::Text.extract(text, schema: { name: :string, age: :integer })
52
+
53
+ # Classify text
54
+ review = "This product is amazing!"
55
+ sentiment = RubyLLM::Text.classify(review, categories: ["positive", "negative", "neutral"])
56
+ ```
57
+
58
+ ## API Reference
59
+
60
+ ### Summarize
61
+
62
+ Condense text into a shorter summary.
63
+
64
+ ```ruby
65
+ RubyLLM::Text.summarize(text, length: :medium, max_words: nil, model: nil)
66
+ ```
67
+
68
+ **Parameters:**
69
+ - `text` (String): The text to summarize
70
+ - `length` (Symbol|String): Predefined length (`:short`, `:medium`, `:detailed`) or custom description
71
+ - `max_words` (Integer, optional): Maximum word count for summary
72
+ - `model` (String, optional): Specific model to use
73
+
74
+ **Examples:**
75
+ ```ruby
76
+ # Basic usage
77
+ RubyLLM::Text.summarize("Long article text...")
78
+
79
+ # With length option
80
+ RubyLLM::Text.summarize(text, length: :short)
81
+
82
+ # With word limit
83
+ RubyLLM::Text.summarize(text, length: :medium, max_words: 50)
84
+
85
+ # Custom length description
86
+ RubyLLM::Text.summarize(text, length: "bullet points")
87
+ ```
88
+
89
+ ### Translate
90
+
91
+ Translate text between languages.
92
+
93
+ ```ruby
94
+ RubyLLM::Text.translate(text, to:, from: nil, model: nil)
95
+ ```
96
+
97
+ **Parameters:**
98
+ - `text` (String): The text to translate
99
+ - `to` (String): Target language (e.g., "en", "spanish", "français")
100
+ - `from` (String, optional): Source language for better accuracy
101
+ - `model` (String, optional): Specific model to use
102
+
103
+ **Examples:**
104
+ ```ruby
105
+ # Basic translation
106
+ RubyLLM::Text.translate("Bonjour", to: "en")
107
+
108
+ # With source language specified
109
+ RubyLLM::Text.translate("Hola mundo", to: "en", from: "es")
110
+
111
+ # Natural language specifications
112
+ RubyLLM::Text.translate("Hello", to: "french")
113
+ ```
114
+
115
+ ### Extract
116
+
117
+ Extract structured data from unstructured text.
118
+
119
+ ```ruby
120
+ RubyLLM::Text.extract(text, schema:, model: nil)
121
+ ```
122
+
123
+ **Parameters:**
124
+ - `text` (String): The text to extract data from
125
+ - `schema` (Hash): Data structure specification
126
+ - `model` (String, optional): Specific model to use
127
+
128
+ **Schema Types:**
129
+ - `:string` - Text fields
130
+ - `:integer`, `:number` - Numeric fields
131
+ - `:boolean` - True/false fields
132
+ - `:array` - List fields
133
+
134
+ **Examples:**
135
+ ```ruby
136
+ # Extract person details
137
+ text = "John Smith is 30 years old and works as a software engineer in San Francisco."
138
+ schema = {
139
+ name: :string,
140
+ age: :integer,
141
+ profession: :string,
142
+ location: :string
143
+ }
144
+ data = RubyLLM::Text.extract(text, schema: schema)
145
+
146
+ # Extract product information
147
+ product_text = "iPhone 15 Pro costs $999 and has excellent reviews"
148
+ product_schema = {
149
+ name: :string,
150
+ price: :number,
151
+ currency: :string,
152
+ reviews: :array
153
+ }
154
+ product_data = RubyLLM::Text.extract(product_text, schema: product_schema)
155
+ ```
156
+
157
+ ### Classify
158
+
159
+ Classify text into predefined categories.
160
+
161
+ ```ruby
162
+ RubyLLM::Text.classify(text, categories:, model: nil)
163
+ ```
164
+
165
+ **Parameters:**
166
+ - `text` (String): The text to classify
167
+ - `categories` (Array): List of possible categories
168
+ - `model` (String, optional): Specific model to use
169
+
170
+ **Examples:**
171
+ ```ruby
172
+ # Sentiment analysis
173
+ review = "This product exceeded my expectations!"
174
+ sentiment = RubyLLM::Text.classify(review,
175
+ categories: ["positive", "negative", "neutral"]
176
+ )
177
+
178
+ # Topic classification
179
+ article = "The stock market reached new highs today..."
180
+ topic = RubyLLM::Text.classify(article,
181
+ categories: ["technology", "finance", "sports", "politics"]
182
+ )
183
+
184
+ # Priority classification
185
+ email = "URGENT: Server is down and customers can't access the site"
186
+ priority = RubyLLM::Text.classify(email,
187
+ categories: ["low", "medium", "high", "critical"]
188
+ )
189
+ ```
190
+
191
+ ## Configuration
192
+
193
+ This gem uses `ruby_llm`'s configuration for API keys and default models:
194
+
195
+ ```ruby
196
+ # Configure ruby_llm (API keys, default model, etc.)
197
+ RubyLLM.configure do |config|
198
+ config.openai_api_key = ENV["OPENAI_API_KEY"]
199
+ config.anthropic_api_key = ENV["ANTHROPIC_API_KEY"]
200
+ config.default_model = "gpt-4.1-mini"
201
+ end
202
+ ```
203
+
204
+ Optionally configure text-specific settings:
205
+
206
+ ```ruby
207
+ RubyLLM::Text.configure do |config|
208
+ # Temperature for text operations (default: 0.3)
209
+ config.temperature = 0.3
210
+
211
+ # Method-specific model overrides (falls back to RubyLLM.config.default_model)
212
+ config.summarize_model = "gpt-4.1-mini"
213
+ config.translate_model = "claude-sonnet-4-5" # Use Claude for translation
214
+ config.extract_model = "gpt-4.1" # Use GPT-4 for extraction
215
+ config.classify_model = "gpt-4.1-mini"
216
+ end
217
+ ```
218
+
219
+ **Per-call overrides:**
220
+ ```ruby
221
+ # Override model for specific calls
222
+ RubyLLM::Text.summarize(text, model: "claude-sonnet-4-5")
223
+
224
+ # Pass additional options (passed through to ruby_llm)
225
+ RubyLLM::Text.translate(text, to: "es", temperature: 0.1)
226
+ ```
227
+
228
+ ## String Extensions (Optional)
229
+
230
+ For a more Rails-like experience, you can enable String monkey-patching:
231
+
232
+ ```ruby
233
+ require 'ruby_llm/text/string_ext'
234
+
235
+ # Now you can call methods directly on strings
236
+ "Long article text...".summarize
237
+ "Bonjour".translate(to: "en")
238
+ "John is 30".extract(schema: { name: :string, age: :integer })
239
+ "Great product!".classify(categories: ["positive", "negative"])
240
+ ```
241
+
242
+ ## Integration with ruby_llm
243
+
244
+ This gem builds on top of [ruby_llm](https://github.com/crmne/ruby_llm) and inherits its configuration and model support:
245
+
246
+ - **Models**: Supports all ruby_llm models (OpenAI GPT, Anthropic Claude, etc.)
247
+ - **Configuration**: Uses ruby_llm's underlying configuration system
248
+ - **Error handling**: Inherits ruby_llm's robust error handling
249
+
250
+ ## Error Handling
251
+
252
+ The gem provides clear error messages for common issues:
253
+
254
+ ```ruby
255
+ # Missing required parameters
256
+ RubyLLM::Text.extract("text") # ArgumentError: schema is required
257
+
258
+ RubyLLM::Text.classify("text", categories: []) # ArgumentError: categories are required
259
+
260
+ # API errors are wrapped with context
261
+ RubyLLM::Text.summarize("text") # RubyLLM::Text::Error: LLM call failed: [original error]
262
+ ```
263
+
264
+ ## Development
265
+
266
+ After checking out the repo, run:
267
+
268
+ ```bash
269
+ bin/setup # Install dependencies
270
+ rake test # Run tests
271
+ rake rubocop # Run linter
272
+ rake # Run tests and linter
273
+ ```
274
+
275
+ ## Testing
276
+
277
+ The test suite uses Mocha for mocking LLM API calls, ensuring reliable and fast tests without requiring API keys:
278
+
279
+ ```bash
280
+ # Run all tests
281
+ bundle exec rake test
282
+
283
+ # Run tests with linting
284
+ bundle exec rake
285
+
286
+ # Run linting only
287
+ bundle exec rubocop
288
+ ```
289
+
290
+ ### Manual Testing
291
+
292
+ For manual testing with real API calls, use the provided test script:
293
+
294
+ ```bash
295
+ # Set up your API key
296
+ export OPENAI_API_KEY="your-key"
297
+ # or
298
+ export ANTHROPIC_API_KEY="your-key"
299
+
300
+ # Run manual tests
301
+ bin/manual-test
302
+ ```
303
+
304
+ This script tests all four methods with real LLM APIs and provides helpful output for verification.
305
+
306
+ ## Contributing
307
+
308
+ Bug reports and pull requests are welcome on GitHub at https://github.com/patrols/ruby_llm-text.
309
+
310
+ ## License
311
+
312
+ The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
@@ -0,0 +1,27 @@
1
+ module RubyLLM
2
+ module Text
3
+ module Base
4
+ def self.call_llm(prompt, model: nil, temperature: nil, schema: nil, **options)
5
+ model ||= RubyLLM.config.default_model
6
+ temperature ||= RubyLLM::Text.config.temperature
7
+
8
+ chat = RubyLLM.chat(model: model)
9
+ chat = chat.with_temperature(temperature)
10
+ chat = chat.with_schema(schema) if schema
11
+
12
+ # Apply any additional options
13
+ options.each do |key, value|
14
+ method_name = "with_#{key}"
15
+ chat = chat.send(method_name, value) if chat.respond_to?(method_name)
16
+ end
17
+
18
+ response = chat.ask(prompt)
19
+ response.content
20
+ rescue => e
21
+ raise RubyLLM::Text::Error, "LLM call failed: #{e.message}"
22
+ end
23
+ end
24
+
25
+ class Error < StandardError; end
26
+ end
27
+ end
@@ -0,0 +1,29 @@
1
+ module RubyLLM
2
+ module Text
3
+ module Classify
4
+ def self.call(text, categories:, model: nil, **options)
5
+ model ||= RubyLLM::Text.config.model_for(:classify)
6
+ raise ArgumentError, "categories are required" if categories.empty?
7
+
8
+ prompt = build_prompt(text, categories)
9
+ Base.call_llm(prompt, model: model, **options)
10
+ end
11
+
12
+ private
13
+
14
+ def self.build_prompt(text, categories)
15
+ category_list = categories.map { |c| "- #{c}" }.join("\n")
16
+
17
+ <<~PROMPT
18
+ Classify the following text into one of these categories:
19
+ #{category_list}
20
+
21
+ Return only the category name, nothing else.
22
+
23
+ Text:
24
+ #{text}
25
+ PROMPT
26
+ end
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,25 @@
1
+ module RubyLLM
2
+ module Text
3
+ class Configuration
4
+ # Method-specific model overrides (optional)
5
+ # If not set, falls back to RubyLLM.config.default_model
6
+ attr_accessor :summarize_model, :translate_model,
7
+ :extract_model, :classify_model
8
+
9
+ # Default temperature for text operations
10
+ attr_accessor :temperature
11
+
12
+ def initialize
13
+ @temperature = 0.3
14
+ @summarize_model = nil
15
+ @translate_model = nil
16
+ @extract_model = nil
17
+ @classify_model = nil
18
+ end
19
+
20
+ def model_for(method_name)
21
+ instance_variable_get("@#{method_name}_model") || RubyLLM.config.default_model
22
+ end
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,55 @@
1
+ require "ruby_llm/schema"
2
+
3
+ module RubyLLM
4
+ module Text
5
+ module Extract
6
+ def self.call(text, schema: nil, model: nil, **options)
7
+ model ||= RubyLLM::Text.config.model_for(:extract)
8
+ raise ArgumentError, "schema is required for extraction" unless schema
9
+
10
+ # Convert simple hash schema to RubyLLM::Schema
11
+ schema_obj = build_schema(schema)
12
+ prompt = build_prompt(text, schema)
13
+
14
+ Base.call_llm(prompt, model: model, schema: schema_obj, **options)
15
+ end
16
+
17
+ private
18
+
19
+ def self.build_schema(schema)
20
+ # If already a schema object, return as-is
21
+ return schema if schema.respond_to?(:schema)
22
+
23
+ # Build dynamic schema class from hash
24
+ schema_class = Class.new(RubyLLM::Schema)
25
+ schema.each do |field, type|
26
+ case type
27
+ when :string
28
+ schema_class.string field
29
+ when :integer, :number
30
+ schema_class.number field
31
+ when :boolean
32
+ schema_class.boolean field
33
+ when :array
34
+ schema_class.array field
35
+ else
36
+ schema_class.string field # fallback to string
37
+ end
38
+ end
39
+ schema_class
40
+ end
41
+
42
+ def self.build_prompt(text, schema)
43
+ fields = schema.keys.join(", ")
44
+
45
+ <<~PROMPT
46
+ Extract the following information from the text: #{fields}
47
+ Return the data as structured JSON matching the provided schema.
48
+
49
+ Text:
50
+ #{text}
51
+ PROMPT
52
+ end
53
+ end
54
+ end
55
+ end
@@ -0,0 +1,18 @@
1
+ # Optional String monkey-patching
2
+ class String
3
+ def summarize(**options)
4
+ RubyLLM::Text.summarize(self, **options)
5
+ end
6
+
7
+ def translate(**options)
8
+ RubyLLM::Text.translate(self, **options)
9
+ end
10
+
11
+ def extract(**options)
12
+ RubyLLM::Text.extract(self, **options)
13
+ end
14
+
15
+ def classify(**options)
16
+ RubyLLM::Text.classify(self, **options)
17
+ end
18
+ end
@@ -0,0 +1,34 @@
1
+ module RubyLLM
2
+ module Text
3
+ module Summarize
4
+ LENGTHS = {
5
+ short: "1-2 sentences",
6
+ medium: "3-5 sentences",
7
+ detailed: "1-2 paragraphs"
8
+ }.freeze
9
+
10
+ def self.call(text, length: :medium, max_words: nil, model: nil, **options)
11
+ model ||= RubyLLM::Text.config.model_for(:summarize)
12
+
13
+ prompt = build_prompt(text, length: length, max_words: max_words)
14
+ Base.call_llm(prompt, model: model, **options)
15
+ end
16
+
17
+ private
18
+
19
+ def self.build_prompt(text, length:, max_words:)
20
+ length_instruction = LENGTHS[length] || length.to_s
21
+ word_limit = max_words ? " (maximum #{max_words} words)" : ""
22
+
23
+ <<~PROMPT
24
+ Summarize the following text.
25
+ Length: #{length_instruction}#{word_limit}
26
+ Return only the summary, no preamble or explanation.
27
+
28
+ Text:
29
+ #{text}
30
+ PROMPT
31
+ end
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,26 @@
1
+ module RubyLLM
2
+ module Text
3
+ module Translate
4
+ def self.call(text, to:, from: nil, model: nil, **options)
5
+ model ||= RubyLLM::Text.config.model_for(:translate)
6
+
7
+ prompt = build_prompt(text, to: to, from: from)
8
+ Base.call_llm(prompt, model: model, **options)
9
+ end
10
+
11
+ private
12
+
13
+ def self.build_prompt(text, to:, from:)
14
+ from_instruction = from ? "from #{from} " : ""
15
+
16
+ <<~PROMPT
17
+ Translate the following text #{from_instruction}to #{to}.
18
+ Return only the translated text, no explanation or notes.
19
+
20
+ Text:
21
+ #{text}
22
+ PROMPT
23
+ end
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,5 @@
1
+ module RubyLLM
2
+ module Text
3
+ VERSION = "0.1.0"
4
+ end
5
+ end
@@ -0,0 +1,40 @@
1
+ require "ruby_llm"
2
+ require_relative "text/version"
3
+ require_relative "text/configuration"
4
+ require_relative "text/base"
5
+ require_relative "text/summarize"
6
+ require_relative "text/translate"
7
+ require_relative "text/extract"
8
+ require_relative "text/classify"
9
+
10
+ module RubyLLM
11
+ module Text
12
+ class << self
13
+ def configure(&block)
14
+ config.instance_eval(&block) if block_given?
15
+ config
16
+ end
17
+
18
+ def config
19
+ @config ||= Configuration.new
20
+ end
21
+
22
+ # Module-style API methods
23
+ def summarize(text, **options)
24
+ Summarize.call(text, **options)
25
+ end
26
+
27
+ def translate(text, **options)
28
+ Translate.call(text, **options)
29
+ end
30
+
31
+ def extract(text, **options)
32
+ Extract.call(text, **options)
33
+ end
34
+
35
+ def classify(text, **options)
36
+ Classify.call(text, **options)
37
+ end
38
+ end
39
+ end
40
+ end
metadata ADDED
@@ -0,0 +1,127 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: ruby_llm-text
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Patrick Rendal Olsen
8
+ bindir: bin
9
+ cert_chain: []
10
+ date: 1980-01-02 00:00:00.000000000 Z
11
+ dependencies:
12
+ - !ruby/object:Gem::Dependency
13
+ name: ruby_llm
14
+ requirement: !ruby/object:Gem::Requirement
15
+ requirements:
16
+ - - "~>"
17
+ - !ruby/object:Gem::Version
18
+ version: '1.0'
19
+ type: :runtime
20
+ prerelease: false
21
+ version_requirements: !ruby/object:Gem::Requirement
22
+ requirements:
23
+ - - "~>"
24
+ - !ruby/object:Gem::Version
25
+ version: '1.0'
26
+ - !ruby/object:Gem::Dependency
27
+ name: minitest
28
+ requirement: !ruby/object:Gem::Requirement
29
+ requirements:
30
+ - - ">="
31
+ - !ruby/object:Gem::Version
32
+ version: '5.20'
33
+ type: :development
34
+ prerelease: false
35
+ version_requirements: !ruby/object:Gem::Requirement
36
+ requirements:
37
+ - - ">="
38
+ - !ruby/object:Gem::Version
39
+ version: '5.20'
40
+ - !ruby/object:Gem::Dependency
41
+ name: mocha
42
+ requirement: !ruby/object:Gem::Requirement
43
+ requirements:
44
+ - - ">="
45
+ - !ruby/object:Gem::Version
46
+ version: '2.0'
47
+ type: :development
48
+ prerelease: false
49
+ version_requirements: !ruby/object:Gem::Requirement
50
+ requirements:
51
+ - - ">="
52
+ - !ruby/object:Gem::Version
53
+ version: '2.0'
54
+ - !ruby/object:Gem::Dependency
55
+ name: rubocop-rails-omakase
56
+ requirement: !ruby/object:Gem::Requirement
57
+ requirements:
58
+ - - "~>"
59
+ - !ruby/object:Gem::Version
60
+ version: '1.0'
61
+ type: :development
62
+ prerelease: false
63
+ version_requirements: !ruby/object:Gem::Requirement
64
+ requirements:
65
+ - - "~>"
66
+ - !ruby/object:Gem::Version
67
+ version: '1.0'
68
+ - !ruby/object:Gem::Dependency
69
+ name: rake
70
+ requirement: !ruby/object:Gem::Requirement
71
+ requirements:
72
+ - - "~>"
73
+ - !ruby/object:Gem::Version
74
+ version: '13.0'
75
+ type: :development
76
+ prerelease: false
77
+ version_requirements: !ruby/object:Gem::Requirement
78
+ requirements:
79
+ - - "~>"
80
+ - !ruby/object:Gem::Version
81
+ version: '13.0'
82
+ description: Intuitive one-liner utility methods for common LLM tasks like summarize,
83
+ translate, extract, and classify.
84
+ email:
85
+ - patrick@rendal.me
86
+ executables: []
87
+ extensions: []
88
+ extra_rdoc_files: []
89
+ files:
90
+ - CHANGELOG.md
91
+ - LICENSE
92
+ - README.md
93
+ - lib/ruby_llm/text.rb
94
+ - lib/ruby_llm/text/base.rb
95
+ - lib/ruby_llm/text/classify.rb
96
+ - lib/ruby_llm/text/configuration.rb
97
+ - lib/ruby_llm/text/extract.rb
98
+ - lib/ruby_llm/text/string_ext.rb
99
+ - lib/ruby_llm/text/summarize.rb
100
+ - lib/ruby_llm/text/translate.rb
101
+ - lib/ruby_llm/text/version.rb
102
+ homepage: https://github.com/patrols/ruby_llm-text
103
+ licenses:
104
+ - MIT
105
+ metadata:
106
+ allowed_push_host: https://rubygems.org
107
+ homepage_uri: https://github.com/patrols/ruby_llm-text
108
+ source_code_uri: https://github.com/patrols/ruby_llm-text.git
109
+ changelog_uri: https://github.com/patrols/ruby_llm-text/blob/main/CHANGELOG.md
110
+ rdoc_options: []
111
+ require_paths:
112
+ - lib
113
+ required_ruby_version: !ruby/object:Gem::Requirement
114
+ requirements:
115
+ - - ">="
116
+ - !ruby/object:Gem::Version
117
+ version: 3.2.0
118
+ required_rubygems_version: !ruby/object:Gem::Requirement
119
+ requirements:
120
+ - - ">="
121
+ - !ruby/object:Gem::Version
122
+ version: '0'
123
+ requirements: []
124
+ rubygems_version: 4.0.6
125
+ specification_version: 4
126
+ summary: ActiveSupport-style LLM utilities for Ruby
127
+ test_files: []