llm_conductor 0.1.1 → 1.0.1
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 +4 -4
- data/.rubocop.yml +16 -12
- data/README.md +37 -32
- data/config/initializers/llm_conductor.rb +2 -1
- data/lib/llm_conductor/clients/base_client.rb +21 -1
- data/lib/llm_conductor/configuration.rb +2 -1
- data/lib/llm_conductor/prompts.rb +112 -96
- data/lib/llm_conductor/version.rb +1 -1
- data/lib/llm_conductor.rb +4 -3
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 00742db531ea95e6247acbb8b7ea7e92619df851b0d558fd33a4f20d8cf23873
|
4
|
+
data.tar.gz: 9492982bc533d2552b9b55f8e0892fc523c2340d75086ade217651bf9d72730a
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 8d23aa8d06cc823d77ec4992605208f693a592971d13f88266d587cf06fe78cd42111b7904404cc998215736df1d2b9acf452c5474d070401619d6774a870993
|
7
|
+
data.tar.gz: 154240f949c96860372b6cc6eb097267c1a4e9a52b6da968dc30f53d18069f4034fdadfe12fe38b51e5be99d54f75988f1aa48864b624635ce63077bc7f8da6f
|
data/.rubocop.yml
CHANGED
@@ -2,8 +2,6 @@
|
|
2
2
|
plugins:
|
3
3
|
- rubocop-performance
|
4
4
|
- rubocop-rake
|
5
|
-
|
6
|
-
require:
|
7
5
|
- rubocop-capybara
|
8
6
|
- rubocop-factory_bot
|
9
7
|
- rubocop-rspec
|
@@ -27,21 +25,14 @@ Style/StringLiteralsInInterpolation:
|
|
27
25
|
|
28
26
|
Style/HashSyntax:
|
29
27
|
EnforcedShorthandSyntax: always
|
30
|
-
# This is not rails application.
|
31
|
-
# Rails/Blank:
|
32
|
-
# Enabled: false
|
33
|
-
|
34
|
-
# Rails/Present:
|
35
|
-
# Enabled: false
|
36
|
-
|
37
|
-
# Rails/TimeZone:
|
38
|
-
# Enabled: false
|
39
28
|
|
40
29
|
Lint/ConstantDefinitionInBlock:
|
41
30
|
Enabled: false
|
42
31
|
|
43
32
|
Metrics/MethodLength:
|
44
33
|
Max: 15
|
34
|
+
Exclude:
|
35
|
+
- 'lib/llm_conductor/prompts.rb'
|
45
36
|
|
46
37
|
RSpec/ExampleLength:
|
47
38
|
Enabled: false
|
@@ -67,7 +58,7 @@ RSpec/MultipleDescribes:
|
|
67
58
|
RSpec/SpecFilePathFormat:
|
68
59
|
Enabled: false
|
69
60
|
|
70
|
-
RSpec/
|
61
|
+
RSpec/SpecFilePathSuffix:
|
71
62
|
Enabled: false
|
72
63
|
|
73
64
|
RSpec/UnspecifiedException:
|
@@ -94,6 +85,19 @@ Metrics/BlockLength:
|
|
94
85
|
Exclude:
|
95
86
|
- '*.gemspec'
|
96
87
|
|
88
|
+
# Prompt template methods naturally have high complexity due to conditional string building
|
89
|
+
Metrics/AbcSize:
|
90
|
+
Exclude:
|
91
|
+
- 'lib/llm_conductor/prompts.rb'
|
92
|
+
|
93
|
+
Metrics/CyclomaticComplexity:
|
94
|
+
Exclude:
|
95
|
+
- 'lib/llm_conductor/prompts.rb'
|
96
|
+
|
97
|
+
Metrics/PerceivedComplexity:
|
98
|
+
Exclude:
|
99
|
+
- 'lib/llm_conductor/prompts.rb'
|
100
|
+
|
97
101
|
Layout/LineLength:
|
98
102
|
Max: 120
|
99
103
|
|
data/README.md
CHANGED
@@ -52,14 +52,18 @@ puts response.estimated_cost # Cost in USD
|
|
52
52
|
### 2. Template-Based Generation
|
53
53
|
|
54
54
|
```ruby
|
55
|
-
# Use built-in
|
55
|
+
# Use built-in text summarization template
|
56
56
|
response = LlmConductor.generate(
|
57
57
|
model: 'gpt-5-mini',
|
58
|
-
type: :
|
58
|
+
type: :summarize_text,
|
59
59
|
data: {
|
60
|
-
|
61
|
-
|
62
|
-
|
60
|
+
text: 'Ekohe (ee-koh-hee) means "boundless possibility." Our way is to make AI practical, achievable, and most importantly, useful for you — and we prove it every day. With almost 16 years of wins under our belt, a market-leading 24-hr design & development cycle, and 5 offices in the most vibrant cities in the world, we surf the seas of innovation. We create efficient, elegant, and scalable digital products — delivering the right interactive solutions to achieve your audience and business goals. We help you transform. We break new ground across the globe — from AI and ML automation that drives the enterprise, to innovative customer experiences and mobile apps for startups. Our special sauce is the care, curiosity, and dedication we offer to solve for your needs. We focus on your success and deliver the most impactful experiences in the most efficient manner. Our clients tell us we partner with them in a trusted and capable way, driving the right design and technical choices.',
|
61
|
+
max_length: '20 words',
|
62
|
+
style: 'professional and engaging',
|
63
|
+
focus_areas: ['core business', 'expertise', 'target market'],
|
64
|
+
audience: 'potential investors',
|
65
|
+
include_key_points: true,
|
66
|
+
output_format: 'paragraph'
|
63
67
|
}
|
64
68
|
)
|
65
69
|
|
@@ -67,7 +71,7 @@ response = LlmConductor.generate(
|
|
67
71
|
if response.success?
|
68
72
|
puts "Generated: #{response.output}"
|
69
73
|
puts "Tokens: #{response.total_tokens}"
|
70
|
-
puts "Cost: $#{response.estimated_cost}"
|
74
|
+
puts "Cost: $#{response.estimated_cost || 'N/A (free model)'}"
|
71
75
|
else
|
72
76
|
puts "Error: #{response.metadata[:error]}"
|
73
77
|
end
|
@@ -105,6 +109,33 @@ LlmConductor.configure do |config|
|
|
105
109
|
config.ollama(
|
106
110
|
base_url: ENV['OLLAMA_ADDRESS'] || 'http://localhost:11434'
|
107
111
|
)
|
112
|
+
|
113
|
+
# Optional: Configure custom logger
|
114
|
+
config.logger = Logger.new($stdout) # Log to stdout
|
115
|
+
config.logger = Logger.new('log/llm_conductor.log') # Log to file
|
116
|
+
config.logger = Rails.logger # Use Rails logger (in Rails apps)
|
117
|
+
end
|
118
|
+
```
|
119
|
+
|
120
|
+
### Logging Configuration
|
121
|
+
|
122
|
+
LLM Conductor supports flexible logging using Ruby's built-in Logger class. By default, when a logger is configured, it uses the DEBUG log level to provide detailed information during development.
|
123
|
+
|
124
|
+
```ruby
|
125
|
+
LlmConductor.configure do |config|
|
126
|
+
# Option 1: Log to stdout - uses DEBUG level by default
|
127
|
+
config.logger = Logger.new($stdout)
|
128
|
+
|
129
|
+
# Option 2: Log to file - set appropriate level
|
130
|
+
config.logger = Logger.new('log/llm_conductor.log')
|
131
|
+
|
132
|
+
# Option 3: Use Rails logger (Rails apps)
|
133
|
+
config.logger = Rails.logger
|
134
|
+
|
135
|
+
# Option 4: Custom logger with formatting
|
136
|
+
config.logger = Logger.new($stderr).tap do |logger|
|
137
|
+
logger.formatter = proc { |severity, datetime, progname, msg| "#{msg}\n" }
|
138
|
+
end
|
108
139
|
end
|
109
140
|
```
|
110
141
|
|
@@ -143,20 +174,6 @@ response = LlmConductor.generate(
|
|
143
174
|
)
|
144
175
|
```
|
145
176
|
|
146
|
-
**Supported Claude Models:**
|
147
|
-
- `claude-3-5-sonnet-20241022` (Latest Claude 3.5 Sonnet)
|
148
|
-
- `claude-3-5-haiku-20241022` (Claude 3.5 Haiku)
|
149
|
-
- `claude-3-opus-20240229` (Claude 3 Opus)
|
150
|
-
- `claude-3-sonnet-20240229` (Claude 3 Sonnet)
|
151
|
-
- `claude-3-haiku-20240307` (Claude 3 Haiku)
|
152
|
-
|
153
|
-
**Why Choose Claude?**
|
154
|
-
- **Superior Reasoning**: Excellent for complex analysis and problem-solving
|
155
|
-
- **Code Generation**: Outstanding performance for programming tasks
|
156
|
-
- **Long Context**: Support for large documents and conversations
|
157
|
-
- **Safety**: Built with safety and helpfulness in mind
|
158
|
-
- **Cost Effective**: Competitive pricing for high-quality outputs
|
159
|
-
|
160
177
|
### Google Gemini (Automatic for Gemini models)
|
161
178
|
```ruby
|
162
179
|
response = LlmConductor.generate(
|
@@ -172,18 +189,6 @@ response = LlmConductor.generate(
|
|
172
189
|
)
|
173
190
|
```
|
174
191
|
|
175
|
-
**Supported Gemini Models:**
|
176
|
-
- `gemini-2.5-flash` (Latest Gemini 2.5 Flash)
|
177
|
-
- `gemini-2.5-flash` (Gemini 2.5 Flash)
|
178
|
-
- `gemini-2.0-flash` (Gemini 2.0 Flash)
|
179
|
-
|
180
|
-
**Why Choose Gemini?**
|
181
|
-
- **Multimodal**: Native support for text, images, and other modalities
|
182
|
-
- **Long Context**: Massive context windows for large documents
|
183
|
-
- **Fast Performance**: Optimized for speed and efficiency
|
184
|
-
- **Google Integration**: Seamless integration with Google services
|
185
|
-
- **Competitive Pricing**: Cost-effective for high-volume usage
|
186
|
-
|
187
192
|
### Ollama (Default for non-GPT/Claude/Gemini models)
|
188
193
|
```ruby
|
189
194
|
response = LlmConductor.generate(
|
@@ -10,7 +10,8 @@ LlmConductor.configure do |config|
|
|
10
10
|
config.timeout = 30
|
11
11
|
config.max_retries = 3
|
12
12
|
config.retry_delay = 1.0
|
13
|
-
|
13
|
+
# Use Ruby's built-in Logger class directly
|
14
|
+
config.logger = Logger.new($stdout)
|
14
15
|
# Configure providers
|
15
16
|
config.openai(
|
16
17
|
api_key: ENV['OPENAI_API_KEY'],
|
@@ -24,6 +24,12 @@ module LlmConductor
|
|
24
24
|
output_text = generate_content(prompt)
|
25
25
|
output_tokens = calculate_tokens(output_text || '')
|
26
26
|
|
27
|
+
# Logging AI request metadata if logger is set
|
28
|
+
configuration.logger&.debug(
|
29
|
+
"Vendor: #{vendor_name}, Model: #{@model} " \
|
30
|
+
"Output_tokens: #{output_tokens} Input_tokens: #{input_tokens}"
|
31
|
+
)
|
32
|
+
|
27
33
|
build_response(output_text, input_tokens, output_tokens, { prompt: })
|
28
34
|
rescue StandardError => e
|
29
35
|
build_error_response(e)
|
@@ -35,6 +41,12 @@ module LlmConductor
|
|
35
41
|
output_text = generate_content(prompt)
|
36
42
|
output_tokens = calculate_tokens(output_text || '')
|
37
43
|
|
44
|
+
# Logging AI request metadata if logger is set
|
45
|
+
configuration.logger&.debug(
|
46
|
+
"Vendor: #{vendor_name}, Model: #{@model} " \
|
47
|
+
"Output_tokens: #{output_tokens} Input_tokens: #{input_tokens}"
|
48
|
+
)
|
49
|
+
|
38
50
|
build_response(output_text, input_tokens, output_tokens)
|
39
51
|
rescue StandardError => e
|
40
52
|
build_error_response(e)
|
@@ -89,10 +101,18 @@ module LlmConductor
|
|
89
101
|
# Build metadata for the response
|
90
102
|
def build_metadata
|
91
103
|
{
|
92
|
-
vendor:
|
104
|
+
vendor: vendor_name,
|
93
105
|
timestamp: Time.now.utc.iso8601
|
94
106
|
}
|
95
107
|
end
|
108
|
+
|
109
|
+
def vendor_name
|
110
|
+
self.class.name.split('::').last.gsub('Client', '').downcase.to_sym
|
111
|
+
end
|
112
|
+
|
113
|
+
def configuration
|
114
|
+
LlmConductor.configuration
|
115
|
+
end
|
96
116
|
end
|
97
117
|
end
|
98
118
|
end
|
@@ -4,7 +4,7 @@
|
|
4
4
|
module LlmConductor
|
5
5
|
# Configuration class for managing API keys, endpoints, and default settings
|
6
6
|
class Configuration
|
7
|
-
attr_accessor :default_model, :default_vendor, :timeout, :max_retries, :retry_delay
|
7
|
+
attr_accessor :default_model, :default_vendor, :timeout, :max_retries, :retry_delay, :logger
|
8
8
|
attr_reader :providers
|
9
9
|
|
10
10
|
def initialize
|
@@ -14,6 +14,7 @@ module LlmConductor
|
|
14
14
|
@timeout = 30
|
15
15
|
@max_retries = 3
|
16
16
|
@retry_delay = 1.0
|
17
|
+
@logger = nil
|
17
18
|
|
18
19
|
# Provider configurations
|
19
20
|
@providers = {}
|
@@ -1,124 +1,140 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
module LlmConductor
|
4
|
-
# Collection of
|
5
|
-
# content analysis, link extraction, and data summarization.
|
4
|
+
# Collection of general-purpose prompt templates for common LLM tasks
|
6
5
|
module Prompts
|
7
|
-
|
6
|
+
# General prompt for extracting links from HTML content
|
7
|
+
# More flexible and applicable to various use cases
|
8
|
+
def prompt_extract_links(data)
|
9
|
+
criteria = data[:criteria] || 'relevant and useful'
|
10
|
+
max_links = data[:max_links] || 10
|
11
|
+
link_types = data[:link_types] || %w[navigation content footer]
|
12
|
+
|
8
13
|
<<~PROMPT
|
9
|
-
|
14
|
+
Analyze the provided HTML content and extract links based on the specified criteria.
|
15
|
+
|
16
|
+
HTML Content:
|
17
|
+
#{data[:html_content] || data[:htmls]}
|
18
|
+
|
19
|
+
Extraction Criteria: #{criteria}
|
20
|
+
Maximum Links: #{max_links}
|
21
|
+
Link Types to Consider: #{link_types.join(', ')}
|
10
22
|
|
11
|
-
|
12
|
-
<page_html>
|
13
|
-
#{data[:htmls]}
|
14
|
-
</page_html>
|
23
|
+
#{"Domain Filter: Only include links from domain #{data[:domain_filter]}" if data[:domain_filter]}
|
15
24
|
|
16
|
-
|
25
|
+
Instructions:
|
26
|
+
1. Parse the HTML content and identify all hyperlinks
|
27
|
+
2. Filter links based on the provided criteria
|
28
|
+
3. Prioritize links from specified areas: #{link_types.join(', ')}
|
29
|
+
4. Return up to #{max_links} most relevant links
|
30
|
+
#{if data[:format] == :json
|
31
|
+
'5. Format output as a JSON array of URLs'
|
32
|
+
else
|
33
|
+
'5. Format output as a newline-separated list of URLs'
|
34
|
+
end}
|
17
35
|
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
c. Include social media profile links (e.g., LinkedIn, Instagram, Twitter, Facebook) if available.
|
22
|
-
d. Exclude links to login pages, search pages, or other utility pages.
|
36
|
+
Provide only the links without additional commentary.
|
37
|
+
PROMPT
|
38
|
+
end
|
23
39
|
|
24
|
-
|
40
|
+
# General prompt for content analysis and data extraction
|
41
|
+
# Flexible template for various content analysis tasks
|
42
|
+
def prompt_analyze_content(data)
|
43
|
+
content_type = data[:content_type] || 'webpage content'
|
44
|
+
analysis_fields = data[:fields] || %w[summary key_points entities]
|
45
|
+
output_format = data[:output_format] || 'structured text'
|
25
46
|
|
26
|
-
|
27
|
-
|
28
|
-
["https://example.com/about-us", "https://example.com/products", "https://example.com/services"]
|
29
|
-
</output_format>
|
47
|
+
<<~PROMPT
|
48
|
+
Analyze the provided #{content_type} and extract the requested information.
|
30
49
|
|
31
|
-
|
32
|
-
|
33
|
-
#{data[:current_url]}
|
34
|
-
</domain>
|
50
|
+
Content:
|
51
|
+
#{data[:content] || data[:htmls] || data[:text]}
|
35
52
|
|
36
|
-
|
53
|
+
Analysis Fields:
|
54
|
+
#{analysis_fields.map { |field| "- #{field}" }.join("\n")}
|
37
55
|
|
38
|
-
|
56
|
+
#{"Additional Instructions:\n#{data[:instructions]}" if data[:instructions]}
|
39
57
|
|
40
|
-
|
58
|
+
#{if output_format == 'json'
|
59
|
+
json_structure = analysis_fields.map { |field| " \"#{field}\": \"value or array\"" }.join(",\n")
|
60
|
+
"Output Format: JSON with the following structure:\n{\n#{json_structure}\n}"
|
61
|
+
else
|
62
|
+
"Output Format: #{output_format}"
|
63
|
+
end}
|
64
|
+
|
65
|
+
#{"Constraints:\n#{data[:constraints]}" if data[:constraints]}
|
66
|
+
|
67
|
+
Provide a comprehensive analysis focusing on the requested fields.
|
41
68
|
PROMPT
|
42
69
|
end
|
43
70
|
|
44
|
-
|
71
|
+
# General prompt for text summarization
|
72
|
+
# Applicable to various types of text content
|
73
|
+
def prompt_summarize_text(data)
|
74
|
+
max_length = data[:max_length] || '200 words'
|
75
|
+
focus_areas = data[:focus_areas] || []
|
76
|
+
style = data[:style] || 'concise and informative'
|
77
|
+
|
45
78
|
<<~PROMPT
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
#{
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
- Product description(product_description): A brief overview of the company's main product(s) or service(s)
|
67
|
-
- Product features(product_features): Key features or capabilities of the product(s) or service(s)
|
68
|
-
- Customers and partners(field customers_and_partners): Notable clients or business partners
|
69
|
-
- Development stage(field development_stage): The current phase of the company (e.g., startup, growth, established)
|
70
|
-
- Social media links(field social_media_links): URLs to the company's social media profiles
|
71
|
-
- instagram_url
|
72
|
-
- linkedin_url
|
73
|
-
- twitter_url
|
74
|
-
|
75
|
-
If any of the above information is not available in the webpage content, use "Not available" as the value for that field.
|
76
|
-
|
77
|
-
Present your findings in a JSON format. Here's an example of the expected structure:
|
78
|
-
|
79
|
-
<output_format>
|
80
|
-
{
|
81
|
-
"name": "AI-powered customer service",
|
82
|
-
"domain_name": "example.com",
|
83
|
-
"description": "XYZ Company develops AI chatbots that help businesses automate customer support...",
|
84
|
-
"founding_on": 2018,
|
85
|
-
"country": "United States",
|
86
|
-
"Region": "SA",
|
87
|
-
"Location": "SFO",
|
88
|
-
"business_model": "SaaS subscription",
|
89
|
-
"product_description": "AI-powered chatbot platform for customer service automation",
|
90
|
-
"product_features": ["Natural language processing", "Multi-language support", "Integration with CRM systems"],
|
91
|
-
"customers_and_partners": ["ABC Corp", "123 Industries", "Big Tech Co."],
|
92
|
-
"development_stage": "Growth",
|
93
|
-
"social_media_links": {
|
94
|
-
"linkedin_url": "https://www.linkedin.com/company/xyzcompany",
|
95
|
-
"twitter_url": "https://twitter.com/xyzcompany",
|
96
|
-
"instagram_url": "https://www.instagram.com/xyzcompany"
|
97
|
-
}
|
98
|
-
}
|
99
|
-
</output_format>
|
100
|
-
|
101
|
-
Remember to use only the information provided in the webpage content. Do not include any external information or make assumptions beyond what is explicitly stated or strongly implied in the given content.
|
102
|
-
|
103
|
-
Present your final output in JSON format, enclosed within <json_output> tags.
|
79
|
+
Summarize the following text content.
|
80
|
+
|
81
|
+
Text:
|
82
|
+
#{data[:text] || data[:content] || data[:description]}
|
83
|
+
|
84
|
+
Summary Requirements:
|
85
|
+
- Maximum Length: #{max_length}
|
86
|
+
- Style: #{style}
|
87
|
+
#{"- Focus Areas: #{focus_areas.join(', ')}" if focus_areas.any?}
|
88
|
+
#{"- Target Audience: #{data[:audience]}" if data[:audience]}
|
89
|
+
|
90
|
+
#{'Include key points and main themes.' if data[:include_key_points]}
|
91
|
+
|
92
|
+
#{if data[:output_format] == 'bullet_points'
|
93
|
+
'Format as bullet points.'
|
94
|
+
elsif data[:output_format] == 'paragraph'
|
95
|
+
'Format as a single paragraph.'
|
96
|
+
end}
|
97
|
+
|
98
|
+
Provide a clear and accurate summary.
|
104
99
|
PROMPT
|
105
100
|
end
|
106
101
|
|
107
|
-
|
102
|
+
# General prompt for data classification and categorization
|
103
|
+
# Useful for various classification tasks
|
104
|
+
def prompt_classify_content(data)
|
105
|
+
categories = data[:categories] || []
|
106
|
+
classification_type = data[:classification_type] || 'content'
|
107
|
+
confidence_scores = data[:include_confidence] || false
|
108
|
+
|
108
109
|
<<~PROMPT
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
110
|
+
Classify the provided #{classification_type} into the most appropriate category.
|
111
|
+
|
112
|
+
Content to Classify:
|
113
|
+
#{data[:content] || data[:text] || data[:description]}
|
114
|
+
|
115
|
+
Available Categories:
|
116
|
+
#{categories.map.with_index(1) { |cat, i| "#{i}. #{cat}" }.join("\n")}
|
117
|
+
|
118
|
+
#{"Classification Criteria:\n#{data[:classification_criteria]}" if data[:classification_criteria]}
|
119
|
+
|
120
|
+
#{if confidence_scores
|
121
|
+
'Output Format: JSON with category and confidence score (0-1)'
|
122
|
+
else
|
123
|
+
'Output Format: Return the most appropriate category name'
|
124
|
+
end}
|
125
|
+
|
126
|
+
#{if data[:multiple_categories]
|
127
|
+
"Note: Multiple categories may apply - select up to #{data[:max_categories] || 3} most relevant."
|
128
|
+
else
|
129
|
+
'Note: Select only the single most appropriate category.'
|
130
|
+
end}
|
131
|
+
|
132
|
+
Provide your classification based on the content analysis.
|
119
133
|
PROMPT
|
120
134
|
end
|
121
135
|
|
136
|
+
# Flexible custom prompt template
|
137
|
+
# Allows for dynamic prompt creation with variable substitution
|
122
138
|
def prompt_custom(data)
|
123
139
|
template = data.fetch(:template)
|
124
140
|
template % data
|
data/lib/llm_conductor.rb
CHANGED
@@ -74,9 +74,10 @@ module LlmConductor
|
|
74
74
|
|
75
75
|
# List of supported prompt types
|
76
76
|
SUPPORTED_PROMPT_TYPES = %i[
|
77
|
-
|
78
|
-
|
79
|
-
|
77
|
+
extract_links
|
78
|
+
analyze_content
|
79
|
+
summarize_text
|
80
|
+
classify_content
|
80
81
|
custom
|
81
82
|
].freeze
|
82
83
|
end
|
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: llm_conductor
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1
|
4
|
+
version: 1.0.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Ben Zheng
|
8
8
|
bindir: exe
|
9
9
|
cert_chain: []
|
10
|
-
date: 2025-
|
10
|
+
date: 2025-10-01 00:00:00.000000000 Z
|
11
11
|
dependencies:
|
12
12
|
- !ruby/object:Gem::Dependency
|
13
13
|
name: activesupport
|