dify_llm 1.7.1 → 1.8.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/README.md +16 -3
- data/lib/dify_llm.rb +3 -0
- data/lib/generators/ruby_llm/chat_ui/chat_ui_generator.rb +14 -2
- data/lib/generators/ruby_llm/chat_ui/templates/jobs/chat_response_job.rb.tt +1 -1
- data/lib/generators/ruby_llm/chat_ui/templates/views/messages/_content.html.erb.tt +1 -0
- data/lib/generators/ruby_llm/chat_ui/templates/views/messages/_message.html.erb.tt +1 -1
- data/lib/generators/ruby_llm/install/install_generator.rb +8 -2
- data/lib/generators/ruby_llm/install/templates/add_references_to_chats_tool_calls_and_messages_migration.rb.tt +9 -0
- data/lib/generators/ruby_llm/install/templates/create_chats_migration.rb.tt +0 -1
- data/lib/generators/ruby_llm/install/templates/create_messages_migration.rb.tt +0 -3
- data/lib/generators/ruby_llm/install/templates/create_tool_calls_migration.rb.tt +0 -1
- data/lib/ruby_llm/attachment.rb +5 -0
- data/lib/ruby_llm/configuration.rb +2 -0
- data/lib/ruby_llm/mime_type.rb +4 -0
- data/lib/ruby_llm/model/info.rb +4 -0
- data/lib/ruby_llm/models.json +1360 -1245
- data/lib/ruby_llm/models.rb +7 -3
- data/lib/ruby_llm/moderation.rb +56 -0
- data/lib/ruby_llm/provider.rb +6 -0
- data/lib/ruby_llm/providers/gemini/capabilities.rb +5 -0
- data/lib/ruby_llm/providers/openai/capabilities.rb +15 -7
- data/lib/ruby_llm/providers/openai/moderation.rb +34 -0
- data/lib/ruby_llm/providers/openai.rb +1 -0
- data/lib/ruby_llm/railtie.rb +1 -1
- data/lib/ruby_llm/version.rb +1 -1
- data/lib/ruby_llm.rb +5 -0
- metadata +10 -4
data/lib/ruby_llm/models.rb
CHANGED
@@ -194,15 +194,15 @@ module RubyLLM
|
|
194
194
|
end
|
195
195
|
|
196
196
|
def embedding_models
|
197
|
-
self.class.new(all.select { |m| m.type == 'embedding' })
|
197
|
+
self.class.new(all.select { |m| m.type == 'embedding' || m.modalities.output.include?('embeddings') })
|
198
198
|
end
|
199
199
|
|
200
200
|
def audio_models
|
201
|
-
self.class.new(all.select { |m| m.type == 'audio' })
|
201
|
+
self.class.new(all.select { |m| m.type == 'audio' || m.modalities.output.include?('audio') })
|
202
202
|
end
|
203
203
|
|
204
204
|
def image_models
|
205
|
-
self.class.new(all.select { |m| m.type == 'image' })
|
205
|
+
self.class.new(all.select { |m| m.type == 'image' || m.modalities.output.include?('image') })
|
206
206
|
end
|
207
207
|
|
208
208
|
def by_family(family)
|
@@ -217,6 +217,10 @@ module RubyLLM
|
|
217
217
|
self.class.refresh!(remote_only: remote_only)
|
218
218
|
end
|
219
219
|
|
220
|
+
def resolve(model_id, provider: nil, assume_exists: false, config: nil)
|
221
|
+
self.class.resolve(model_id, provider: provider, assume_exists: assume_exists, config: config)
|
222
|
+
end
|
223
|
+
|
220
224
|
private
|
221
225
|
|
222
226
|
def find_with_provider(model_id, provider)
|
@@ -0,0 +1,56 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module RubyLLM
|
4
|
+
# Identify potentially harmful content in text.
|
5
|
+
# https://platform.openai.com/docs/guides/moderation
|
6
|
+
class Moderation
|
7
|
+
attr_reader :id, :model, :results
|
8
|
+
|
9
|
+
def initialize(id:, model:, results:)
|
10
|
+
@id = id
|
11
|
+
@model = model
|
12
|
+
@results = results
|
13
|
+
end
|
14
|
+
|
15
|
+
def self.moderate(input,
|
16
|
+
model: nil,
|
17
|
+
provider: nil,
|
18
|
+
assume_model_exists: false,
|
19
|
+
context: nil)
|
20
|
+
config = context&.config || RubyLLM.config
|
21
|
+
model ||= config.default_moderation_model || 'omni-moderation-latest'
|
22
|
+
model, provider_instance = Models.resolve(model, provider: provider, assume_exists: assume_model_exists,
|
23
|
+
config: config)
|
24
|
+
model_id = model.id
|
25
|
+
|
26
|
+
provider_instance.moderate(input, model: model_id)
|
27
|
+
end
|
28
|
+
|
29
|
+
# Convenience method to get content from moderation result
|
30
|
+
def content
|
31
|
+
results
|
32
|
+
end
|
33
|
+
|
34
|
+
# Check if any content was flagged
|
35
|
+
def flagged?
|
36
|
+
results.any? { |result| result['flagged'] }
|
37
|
+
end
|
38
|
+
|
39
|
+
# Get all flagged categories across all results
|
40
|
+
def flagged_categories
|
41
|
+
results.flat_map do |result|
|
42
|
+
result['categories']&.select { |_category, flagged| flagged }&.keys || []
|
43
|
+
end.uniq
|
44
|
+
end
|
45
|
+
|
46
|
+
# Get category scores for the first result (most common case)
|
47
|
+
def category_scores
|
48
|
+
results.first&.dig('category_scores') || {}
|
49
|
+
end
|
50
|
+
|
51
|
+
# Get categories for the first result (most common case)
|
52
|
+
def categories
|
53
|
+
results.first&.dig('categories') || {}
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
data/lib/ruby_llm/provider.rb
CHANGED
@@ -70,6 +70,12 @@ module RubyLLM
|
|
70
70
|
parse_embedding_response(response, model:, text:)
|
71
71
|
end
|
72
72
|
|
73
|
+
def moderate(input, model:)
|
74
|
+
payload = render_moderation_payload(input, model:)
|
75
|
+
response = @connection.post moderation_url, payload
|
76
|
+
parse_moderation_response(response, model:)
|
77
|
+
end
|
78
|
+
|
73
79
|
def paint(prompt, model:, size:)
|
74
80
|
payload = render_image_payload(prompt, model:, size:)
|
75
81
|
response = @connection.post images_url, payload
|
@@ -52,6 +52,10 @@ module RubyLLM
|
|
52
52
|
model_id.match?(/gemini|flash|pro|imagen/)
|
53
53
|
end
|
54
54
|
|
55
|
+
def supports_video?(model_id)
|
56
|
+
model_id.match?(/gemini/)
|
57
|
+
end
|
58
|
+
|
55
59
|
def supports_functions?(model_id)
|
56
60
|
return false if model_id.match?(/text-embedding|embedding-001|aqa|flash-lite|imagen|gemini-2\.0-flash-lite/)
|
57
61
|
|
@@ -217,6 +221,7 @@ module RubyLLM
|
|
217
221
|
modalities[:input] << 'pdf'
|
218
222
|
end
|
219
223
|
|
224
|
+
modalities[:input] << 'video' if supports_video?(model_id)
|
220
225
|
modalities[:input] << 'audio' if model_id.match?(/audio/)
|
221
226
|
modalities[:output] << 'embeddings' if model_id.match?(/embedding|gemini-embedding/)
|
222
227
|
modalities[:output] = ['image'] if model_id.match?(/imagen/)
|
@@ -26,6 +26,9 @@ module RubyLLM
|
|
26
26
|
gpt4o_realtime: /^gpt-4o-realtime/,
|
27
27
|
gpt4o_search: /^gpt-4o-search/,
|
28
28
|
gpt4o_transcribe: /^gpt-4o-transcribe/,
|
29
|
+
gpt5: /^gpt-5/,
|
30
|
+
gpt5_mini: /^gpt-5-mini/,
|
31
|
+
gpt5_nano: /^gpt-5-nano/,
|
29
32
|
o1: /^o1(?!-(?:mini|pro))/,
|
30
33
|
o1_mini: /^o1-mini/,
|
31
34
|
o1_pro: /^o1-pro/,
|
@@ -44,7 +47,7 @@ module RubyLLM
|
|
44
47
|
def context_window_for(model_id)
|
45
48
|
case model_family(model_id)
|
46
49
|
when 'gpt41', 'gpt41_mini', 'gpt41_nano' then 1_047_576
|
47
|
-
when 'chatgpt4o', 'gpt4_turbo', 'gpt4o', 'gpt4o_audio', 'gpt4o_mini',
|
50
|
+
when 'gpt5', 'gpt5_mini', 'gpt5_nano', 'chatgpt4o', 'gpt4_turbo', 'gpt4o', 'gpt4o_audio', 'gpt4o_mini',
|
48
51
|
'gpt4o_mini_audio', 'gpt4o_mini_realtime', 'gpt4o_realtime',
|
49
52
|
'gpt4o_search', 'gpt4o_transcribe', 'gpt4o_mini_search', 'o1_mini' then 128_000
|
50
53
|
when 'gpt4' then 8_192
|
@@ -59,6 +62,7 @@ module RubyLLM
|
|
59
62
|
|
60
63
|
def max_tokens_for(model_id)
|
61
64
|
case model_family(model_id)
|
65
|
+
when 'gpt5', 'gpt5_mini', 'gpt5_nano' then 400_000
|
62
66
|
when 'gpt41', 'gpt41_mini', 'gpt41_nano' then 32_768
|
63
67
|
when 'chatgpt4o', 'gpt4o', 'gpt4o_mini', 'gpt4o_mini_search' then 16_384
|
64
68
|
when 'babbage', 'davinci' then 16_384 # rubocop:disable Lint/DuplicateBranch
|
@@ -76,16 +80,17 @@ module RubyLLM
|
|
76
80
|
|
77
81
|
def supports_vision?(model_id)
|
78
82
|
case model_family(model_id)
|
79
|
-
when '
|
80
|
-
'
|
83
|
+
when 'gpt5', 'gpt5_mini', 'gpt5_nano', 'gpt41', 'gpt41_mini', 'gpt41_nano', 'chatgpt4o', 'gpt4',
|
84
|
+
'gpt4_turbo', 'gpt4o', 'gpt4o_mini', 'o1', 'o1_pro', 'moderation', 'gpt4o_search',
|
85
|
+
'gpt4o_mini_search' then true
|
81
86
|
else false
|
82
87
|
end
|
83
88
|
end
|
84
89
|
|
85
90
|
def supports_functions?(model_id)
|
86
91
|
case model_family(model_id)
|
87
|
-
when '
|
88
|
-
'o3_mini' then true
|
92
|
+
when 'gpt5', 'gpt5_mini', 'gpt5_nano', 'gpt41', 'gpt41_mini', 'gpt41_nano', 'gpt4', 'gpt4_turbo', 'gpt4o',
|
93
|
+
'gpt4o_mini', 'o1', 'o1_pro', 'o3_mini' then true
|
89
94
|
when 'chatgpt4o', 'gpt35_turbo', 'o1_mini', 'gpt4o_mini_tts',
|
90
95
|
'gpt4o_transcribe', 'gpt4o_search', 'gpt4o_mini_search' then false
|
91
96
|
else false # rubocop:disable Lint/DuplicateBranch
|
@@ -94,8 +99,8 @@ module RubyLLM
|
|
94
99
|
|
95
100
|
def supports_structured_output?(model_id)
|
96
101
|
case model_family(model_id)
|
97
|
-
when '
|
98
|
-
'o3_mini' then true
|
102
|
+
when 'gpt5', 'gpt5_mini', 'gpt5_nano', 'gpt41', 'gpt41_mini', 'gpt41_nano', 'chatgpt4o', 'gpt4o',
|
103
|
+
'gpt4o_mini', 'o1', 'o1_pro', 'o3_mini' then true
|
99
104
|
else false
|
100
105
|
end
|
101
106
|
end
|
@@ -105,6 +110,9 @@ module RubyLLM
|
|
105
110
|
end
|
106
111
|
|
107
112
|
PRICES = {
|
113
|
+
gpt5: { input: 1.25, output: 10.0, cached_input: 0.125 },
|
114
|
+
gpt5_mini: { input: 0.25, output: 2.0, cached_input: 0.025 },
|
115
|
+
gpt5_nano: { input: 0.05, output: 0.4, cached_input: 0.005 },
|
108
116
|
gpt41: { input: 2.0, output: 8.0, cached_input: 0.5 },
|
109
117
|
gpt41_mini: { input: 0.4, output: 1.6, cached_input: 0.1 },
|
110
118
|
gpt41_nano: { input: 0.1, output: 0.4 },
|
@@ -0,0 +1,34 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module RubyLLM
|
4
|
+
module Providers
|
5
|
+
class OpenAI
|
6
|
+
# Moderation methods of the OpenAI API integration
|
7
|
+
module Moderation
|
8
|
+
module_function
|
9
|
+
|
10
|
+
def moderation_url
|
11
|
+
'moderations'
|
12
|
+
end
|
13
|
+
|
14
|
+
def render_moderation_payload(input, model:)
|
15
|
+
{
|
16
|
+
model: model,
|
17
|
+
input: input
|
18
|
+
}
|
19
|
+
end
|
20
|
+
|
21
|
+
def parse_moderation_response(response, model:)
|
22
|
+
data = response.body
|
23
|
+
raise Error.new(response, data.dig('error', 'message')) if data.dig('error', 'message')
|
24
|
+
|
25
|
+
RubyLLM::Moderation.new(
|
26
|
+
id: data['id'],
|
27
|
+
model: model,
|
28
|
+
results: data['results'] || []
|
29
|
+
)
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
data/lib/ruby_llm/railtie.rb
CHANGED
data/lib/ruby_llm/version.rb
CHANGED
data/lib/ruby_llm.rb
CHANGED
@@ -28,6 +28,7 @@ loader.inflector.inflect(
|
|
28
28
|
)
|
29
29
|
loader.ignore("#{__dir__}/tasks")
|
30
30
|
loader.ignore("#{__dir__}/generators")
|
31
|
+
loader.ignore("#{__dir__}/dify_llm.rb")
|
31
32
|
loader.setup
|
32
33
|
|
33
34
|
# A delightful Ruby interface to modern AI language models.
|
@@ -49,6 +50,10 @@ module RubyLLM
|
|
49
50
|
Embedding.embed(...)
|
50
51
|
end
|
51
52
|
|
53
|
+
def moderate(...)
|
54
|
+
Moderation.moderate(...)
|
55
|
+
end
|
56
|
+
|
52
57
|
def paint(...)
|
53
58
|
Image.paint(...)
|
54
59
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: dify_llm
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.8.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Carmine Paolino
|
@@ -136,6 +136,7 @@ extra_rdoc_files: []
|
|
136
136
|
files:
|
137
137
|
- LICENSE
|
138
138
|
- README.md
|
139
|
+
- lib/dify_llm.rb
|
139
140
|
- lib/generators/ruby_llm/chat_ui/chat_ui_generator.rb
|
140
141
|
- lib/generators/ruby_llm/chat_ui/templates/controllers/chats_controller.rb.tt
|
141
142
|
- lib/generators/ruby_llm/chat_ui/templates/controllers/messages_controller.rb.tt
|
@@ -146,6 +147,7 @@ files:
|
|
146
147
|
- lib/generators/ruby_llm/chat_ui/templates/views/chats/index.html.erb.tt
|
147
148
|
- lib/generators/ruby_llm/chat_ui/templates/views/chats/new.html.erb.tt
|
148
149
|
- lib/generators/ruby_llm/chat_ui/templates/views/chats/show.html.erb.tt
|
150
|
+
- lib/generators/ruby_llm/chat_ui/templates/views/messages/_content.html.erb.tt
|
149
151
|
- lib/generators/ruby_llm/chat_ui/templates/views/messages/_form.html.erb.tt
|
150
152
|
- lib/generators/ruby_llm/chat_ui/templates/views/messages/_message.html.erb.tt
|
151
153
|
- lib/generators/ruby_llm/chat_ui/templates/views/messages/create.turbo_stream.erb.tt
|
@@ -154,6 +156,7 @@ files:
|
|
154
156
|
- lib/generators/ruby_llm/chat_ui/templates/views/models/show.html.erb.tt
|
155
157
|
- lib/generators/ruby_llm/generator_helpers.rb
|
156
158
|
- lib/generators/ruby_llm/install/install_generator.rb
|
159
|
+
- lib/generators/ruby_llm/install/templates/add_references_to_chats_tool_calls_and_messages_migration.rb.tt
|
157
160
|
- lib/generators/ruby_llm/install/templates/chat_model.rb.tt
|
158
161
|
- lib/generators/ruby_llm/install/templates/create_chats_migration.rb.tt
|
159
162
|
- lib/generators/ruby_llm/install/templates/create_messages_migration.rb.tt
|
@@ -194,6 +197,7 @@ files:
|
|
194
197
|
- lib/ruby_llm/models.json
|
195
198
|
- lib/ruby_llm/models.rb
|
196
199
|
- lib/ruby_llm/models_schema.json
|
200
|
+
- lib/ruby_llm/moderation.rb
|
197
201
|
- lib/ruby_llm/provider.rb
|
198
202
|
- lib/ruby_llm/providers/anthropic.rb
|
199
203
|
- lib/ruby_llm/providers/anthropic/capabilities.rb
|
@@ -252,6 +256,7 @@ files:
|
|
252
256
|
- lib/ruby_llm/providers/openai/images.rb
|
253
257
|
- lib/ruby_llm/providers/openai/media.rb
|
254
258
|
- lib/ruby_llm/providers/openai/models.rb
|
259
|
+
- lib/ruby_llm/providers/openai/moderation.rb
|
255
260
|
- lib/ruby_llm/providers/openai/streaming.rb
|
256
261
|
- lib/ruby_llm/providers/openai/tools.rb
|
257
262
|
- lib/ruby_llm/providers/openrouter.rb
|
@@ -281,10 +286,11 @@ licenses:
|
|
281
286
|
- MIT
|
282
287
|
metadata:
|
283
288
|
homepage_uri: https://github.com/crmne/ruby_llm/pull/168
|
284
|
-
source_code_uri: https://github.com/crmne/ruby_llm
|
285
|
-
changelog_uri: https://github.com/crmne/ruby_llm/commits/main
|
289
|
+
source_code_uri: https://github.com/crmne/ruby_llm/pull/168
|
290
|
+
changelog_uri: https://github.com/crmne/ruby_llm/pull/168/commits/main
|
286
291
|
documentation_uri: https://github.com/crmne/ruby_llm/pull/168
|
287
|
-
bug_tracker_uri: https://github.com/crmne/ruby_llm/issues
|
292
|
+
bug_tracker_uri: https://github.com/crmne/ruby_llm/pull/168/issues
|
293
|
+
funding_uri: https://github.com/sponsors/crmne
|
288
294
|
rubygems_mfa_required: 'true'
|
289
295
|
post_install_message: |
|
290
296
|
Upgrading from RubyLLM <= 1.6.x? Check the upgrade guide for new features and migration instructions
|