ruby_llm 1.13.2 → 1.14.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 +11 -7
- data/lib/generators/ruby_llm/agent/agent_generator.rb +36 -0
- data/lib/generators/ruby_llm/agent/templates/agent.rb.tt +6 -0
- data/lib/generators/ruby_llm/agent/templates/instructions.txt.erb.tt +0 -0
- data/lib/generators/ruby_llm/chat_ui/chat_ui_generator.rb +110 -41
- data/lib/generators/ruby_llm/chat_ui/templates/controllers/chats_controller.rb.tt +14 -15
- data/lib/generators/ruby_llm/chat_ui/templates/controllers/messages_controller.rb.tt +8 -11
- data/lib/generators/ruby_llm/chat_ui/templates/controllers/models_controller.rb.tt +2 -2
- data/lib/generators/ruby_llm/chat_ui/templates/helpers/messages_helper.rb.tt +25 -0
- data/lib/generators/ruby_llm/chat_ui/templates/jobs/chat_response_job.rb.tt +1 -1
- data/lib/generators/ruby_llm/chat_ui/templates/tailwind/views/chats/_chat.html.erb.tt +16 -0
- data/lib/generators/ruby_llm/chat_ui/templates/tailwind/views/chats/_form.html.erb.tt +31 -0
- data/lib/generators/ruby_llm/chat_ui/templates/tailwind/views/chats/index.html.erb.tt +31 -0
- data/lib/generators/ruby_llm/chat_ui/templates/tailwind/views/chats/new.html.erb.tt +9 -0
- data/lib/generators/ruby_llm/chat_ui/templates/tailwind/views/chats/show.html.erb.tt +27 -0
- data/lib/generators/ruby_llm/chat_ui/templates/tailwind/views/messages/_assistant.html.erb.tt +14 -0
- data/lib/generators/ruby_llm/chat_ui/templates/tailwind/views/messages/_content.html.erb.tt +1 -0
- data/lib/generators/ruby_llm/chat_ui/templates/tailwind/views/messages/_error.html.erb.tt +13 -0
- data/lib/generators/ruby_llm/chat_ui/templates/tailwind/views/messages/_form.html.erb.tt +23 -0
- data/lib/generators/ruby_llm/chat_ui/templates/tailwind/views/messages/_system.html.erb.tt +10 -0
- data/lib/generators/ruby_llm/chat_ui/templates/tailwind/views/messages/_tool.html.erb.tt +2 -0
- data/lib/generators/ruby_llm/chat_ui/templates/tailwind/views/messages/_tool_calls.html.erb.tt +4 -0
- data/lib/generators/ruby_llm/chat_ui/templates/tailwind/views/messages/_user.html.erb.tt +14 -0
- data/lib/generators/ruby_llm/chat_ui/templates/tailwind/views/messages/tool_calls/_default.html.erb.tt +13 -0
- data/lib/generators/ruby_llm/chat_ui/templates/tailwind/views/messages/tool_results/_default.html.erb.tt +21 -0
- data/lib/generators/ruby_llm/chat_ui/templates/tailwind/views/models/_model.html.erb.tt +17 -0
- data/lib/generators/ruby_llm/chat_ui/templates/tailwind/views/models/index.html.erb.tt +40 -0
- data/lib/generators/ruby_llm/chat_ui/templates/tailwind/views/models/show.html.erb.tt +27 -0
- data/lib/generators/ruby_llm/chat_ui/templates/views/chats/_chat.html.erb.tt +2 -2
- data/lib/generators/ruby_llm/chat_ui/templates/views/chats/_form.html.erb.tt +2 -2
- data/lib/generators/ruby_llm/chat_ui/templates/views/chats/index.html.erb.tt +19 -7
- data/lib/generators/ruby_llm/chat_ui/templates/views/chats/new.html.erb.tt +1 -1
- data/lib/generators/ruby_llm/chat_ui/templates/views/chats/show.html.erb.tt +5 -3
- data/lib/generators/ruby_llm/chat_ui/templates/views/messages/_assistant.html.erb.tt +9 -0
- data/lib/generators/ruby_llm/chat_ui/templates/views/messages/_content.html.erb.tt +1 -1
- data/lib/generators/ruby_llm/chat_ui/templates/views/messages/_error.html.erb.tt +8 -0
- data/lib/generators/ruby_llm/chat_ui/templates/views/messages/_form.html.erb.tt +1 -1
- data/lib/generators/ruby_llm/chat_ui/templates/views/messages/_system.html.erb.tt +6 -0
- data/lib/generators/ruby_llm/chat_ui/templates/views/messages/_tool.html.erb.tt +2 -0
- data/lib/generators/ruby_llm/chat_ui/templates/views/messages/_tool_calls.html.erb.tt +4 -7
- data/lib/generators/ruby_llm/chat_ui/templates/views/messages/_user.html.erb.tt +9 -0
- data/lib/generators/ruby_llm/chat_ui/templates/views/messages/create.turbo_stream.erb.tt +5 -7
- data/lib/generators/ruby_llm/chat_ui/templates/views/messages/tool_calls/_default.html.erb.tt +8 -0
- data/lib/generators/ruby_llm/chat_ui/templates/views/messages/tool_results/_default.html.erb.tt +16 -0
- data/lib/generators/ruby_llm/chat_ui/templates/views/models/_model.html.erb.tt +11 -12
- data/lib/generators/ruby_llm/chat_ui/templates/views/models/index.html.erb.tt +27 -17
- data/lib/generators/ruby_llm/chat_ui/templates/views/models/show.html.erb.tt +3 -4
- data/lib/generators/ruby_llm/generator_helpers.rb +33 -17
- data/lib/generators/ruby_llm/install/install_generator.rb +21 -18
- data/lib/generators/ruby_llm/install/templates/create_models_migration.rb.tt +3 -4
- data/lib/generators/ruby_llm/install/templates/create_tool_calls_migration.rb.tt +1 -1
- data/lib/generators/ruby_llm/install/templates/initializer.rb.tt +2 -2
- data/lib/generators/ruby_llm/schema/schema_generator.rb +26 -0
- data/lib/generators/ruby_llm/schema/templates/schema.rb.tt +2 -0
- data/lib/generators/ruby_llm/tool/templates/tool.rb.tt +9 -0
- data/lib/generators/ruby_llm/tool/templates/tool_call.html.erb.tt +13 -0
- data/lib/generators/ruby_llm/tool/templates/tool_result.html.erb.tt +13 -0
- data/lib/generators/ruby_llm/tool/tool_generator.rb +96 -0
- data/lib/generators/ruby_llm/upgrade_to_v1_10/upgrade_to_v1_10_generator.rb +1 -1
- data/lib/generators/ruby_llm/upgrade_to_v1_14/templates/add_v1_14_tool_call_columns.rb.tt +7 -0
- data/lib/generators/ruby_llm/upgrade_to_v1_14/upgrade_to_v1_14_generator.rb +49 -0
- data/lib/generators/ruby_llm/upgrade_to_v1_7/upgrade_to_v1_7_generator.rb +2 -4
- data/lib/generators/ruby_llm/upgrade_to_v1_9/upgrade_to_v1_9_generator.rb +1 -1
- data/lib/ruby_llm/active_record/acts_as.rb +2 -0
- data/lib/ruby_llm/active_record/acts_as_legacy.rb +2 -0
- data/lib/ruby_llm/active_record/chat_methods.rb +13 -6
- data/lib/ruby_llm/active_record/message_methods.rb +17 -0
- data/lib/ruby_llm/active_record/model_methods.rb +1 -1
- data/lib/ruby_llm/active_record/payload_helpers.rb +26 -0
- data/lib/ruby_llm/active_record/tool_call_methods.rb +15 -0
- data/lib/ruby_llm/agent.rb +11 -0
- data/lib/ruby_llm/aliases.json +34 -15
- data/lib/ruby_llm/attachment.rb +3 -0
- data/lib/ruby_llm/configuration.rb +54 -73
- data/lib/ruby_llm/connection.rb +1 -3
- data/lib/ruby_llm/error.rb +5 -0
- data/lib/ruby_llm/model/info.rb +14 -12
- data/lib/ruby_llm/models.json +7446 -10126
- data/lib/ruby_llm/models.rb +10 -3
- data/lib/ruby_llm/provider.rb +5 -0
- data/lib/ruby_llm/providers/anthropic/capabilities.rb +1 -133
- data/lib/ruby_llm/providers/anthropic/models.rb +2 -8
- data/lib/ruby_llm/providers/anthropic.rb +4 -0
- data/lib/ruby_llm/providers/azure.rb +4 -0
- data/lib/ruby_llm/providers/bedrock.rb +4 -0
- data/lib/ruby_llm/providers/deepseek/capabilities.rb +1 -119
- data/lib/ruby_llm/providers/deepseek.rb +4 -0
- data/lib/ruby_llm/providers/gemini/capabilities.rb +45 -215
- data/lib/ruby_llm/providers/gemini/models.rb +2 -4
- data/lib/ruby_llm/providers/gemini.rb +4 -0
- data/lib/ruby_llm/providers/gpustack.rb +4 -0
- data/lib/ruby_llm/providers/mistral.rb +4 -0
- data/lib/ruby_llm/providers/ollama.rb +4 -0
- data/lib/ruby_llm/providers/openai/capabilities.rb +95 -203
- data/lib/ruby_llm/providers/openai/models.rb +2 -4
- data/lib/ruby_llm/providers/openai.rb +10 -0
- data/lib/ruby_llm/providers/openrouter/images.rb +1 -1
- data/lib/ruby_llm/providers/openrouter.rb +4 -0
- data/lib/ruby_llm/providers/perplexity/capabilities.rb +34 -99
- data/lib/ruby_llm/providers/perplexity/models.rb +12 -14
- data/lib/ruby_llm/providers/perplexity.rb +4 -0
- data/lib/ruby_llm/providers/vertexai.rb +4 -0
- data/lib/ruby_llm/providers/xai.rb +4 -0
- data/lib/ruby_llm/version.rb +1 -1
- data/lib/tasks/release.rake +1 -1
- data/lib/tasks/ruby_llm.rake +6 -5
- data/lib/tasks/vcr.rake +1 -1
- metadata +49 -11
- data/lib/generators/ruby_llm/chat_ui/templates/views/messages/_message.html.erb.tt +0 -13
data/lib/ruby_llm/models.rb
CHANGED
|
@@ -47,7 +47,8 @@ module RubyLLM
|
|
|
47
47
|
|
|
48
48
|
def read_from_json(file = RubyLLM.config.model_registry_file)
|
|
49
49
|
data = File.exist?(file) ? File.read(file) : '[]'
|
|
50
|
-
JSON.parse(data, symbolize_names: true).map { |model| Model::Info.new(model) }
|
|
50
|
+
models = JSON.parse(data, symbolize_names: true).map { |model| Model::Info.new(model) }
|
|
51
|
+
filter_models(models)
|
|
51
52
|
rescue JSON::ParserError
|
|
52
53
|
[]
|
|
53
54
|
end
|
|
@@ -232,7 +233,13 @@ module RubyLLM
|
|
|
232
233
|
end
|
|
233
234
|
end
|
|
234
235
|
|
|
235
|
-
models.sort_by { |m| [m.provider, m.id] }
|
|
236
|
+
filter_models(models).sort_by { |m| [m.provider, m.id] }
|
|
237
|
+
end
|
|
238
|
+
|
|
239
|
+
def filter_models(models)
|
|
240
|
+
models.reject do |model|
|
|
241
|
+
model.provider.to_s == 'vertexai' && model.id.to_s.include?('/')
|
|
242
|
+
end
|
|
236
243
|
end
|
|
237
244
|
|
|
238
245
|
def find_models_dev_model(key, models_dev_by_key)
|
|
@@ -401,7 +408,7 @@ module RubyLLM
|
|
|
401
408
|
end
|
|
402
409
|
|
|
403
410
|
def initialize(models = nil)
|
|
404
|
-
@models = models || self.class.load_models
|
|
411
|
+
@models = self.class.filter_models(models || self.class.load_models)
|
|
405
412
|
end
|
|
406
413
|
|
|
407
414
|
def load_from_json!(file = RubyLLM.config.model_registry_file)
|
data/lib/ruby_llm/provider.rb
CHANGED
|
@@ -164,6 +164,10 @@ module RubyLLM
|
|
|
164
164
|
[]
|
|
165
165
|
end
|
|
166
166
|
|
|
167
|
+
def configuration_options
|
|
168
|
+
[]
|
|
169
|
+
end
|
|
170
|
+
|
|
167
171
|
def local?
|
|
168
172
|
false
|
|
169
173
|
end
|
|
@@ -182,6 +186,7 @@ module RubyLLM
|
|
|
182
186
|
|
|
183
187
|
def register(name, provider_class)
|
|
184
188
|
providers[name.to_sym] = provider_class
|
|
189
|
+
RubyLLM::Configuration.register_provider_options(provider_class.configuration_options)
|
|
185
190
|
end
|
|
186
191
|
|
|
187
192
|
def resolve(name)
|
|
@@ -3,37 +3,10 @@
|
|
|
3
3
|
module RubyLLM
|
|
4
4
|
module Providers
|
|
5
5
|
class Anthropic
|
|
6
|
-
#
|
|
6
|
+
# Provider-level capability checks used outside the model registry.
|
|
7
7
|
module Capabilities
|
|
8
8
|
module_function
|
|
9
9
|
|
|
10
|
-
def determine_context_window(_model_id)
|
|
11
|
-
200_000
|
|
12
|
-
end
|
|
13
|
-
|
|
14
|
-
def determine_max_tokens(model_id)
|
|
15
|
-
case model_id
|
|
16
|
-
when /claude-3-7-sonnet/, /claude-3-5/ then 8_192
|
|
17
|
-
else 4_096
|
|
18
|
-
end
|
|
19
|
-
end
|
|
20
|
-
|
|
21
|
-
def get_input_price(model_id)
|
|
22
|
-
PRICES.dig(model_family(model_id), :input) || default_input_price
|
|
23
|
-
end
|
|
24
|
-
|
|
25
|
-
def get_output_price(model_id)
|
|
26
|
-
PRICES.dig(model_family(model_id), :output) || default_output_price
|
|
27
|
-
end
|
|
28
|
-
|
|
29
|
-
def supports_vision?(model_id)
|
|
30
|
-
!model_id.match?(/claude-[12]/)
|
|
31
|
-
end
|
|
32
|
-
|
|
33
|
-
def supports_functions?(model_id)
|
|
34
|
-
!model_id.match?(/claude-[12]/)
|
|
35
|
-
end
|
|
36
|
-
|
|
37
10
|
def supports_tool_choice?(_model_id)
|
|
38
11
|
true
|
|
39
12
|
end
|
|
@@ -41,111 +14,6 @@ module RubyLLM
|
|
|
41
14
|
def supports_tool_parallel_control?(_model_id)
|
|
42
15
|
true
|
|
43
16
|
end
|
|
44
|
-
|
|
45
|
-
def supports_json_mode?(model_id)
|
|
46
|
-
!model_id.match?(/claude-[12]/)
|
|
47
|
-
end
|
|
48
|
-
|
|
49
|
-
def supports_structured_output?(model_id)
|
|
50
|
-
match = model_id.match(/claude-(?:sonnet|opus|haiku)-(\d+)-(\d+)/)
|
|
51
|
-
return false unless match
|
|
52
|
-
|
|
53
|
-
major = match[1].to_i
|
|
54
|
-
minor = match[2].to_i
|
|
55
|
-
major > 4 || (major == 4 && minor >= 5)
|
|
56
|
-
end
|
|
57
|
-
|
|
58
|
-
def supports_extended_thinking?(model_id)
|
|
59
|
-
model_id.match?(/claude-3-7-sonnet/)
|
|
60
|
-
end
|
|
61
|
-
|
|
62
|
-
def model_family(model_id)
|
|
63
|
-
case model_id
|
|
64
|
-
when /claude-3-7-sonnet/ then 'claude-3-7-sonnet'
|
|
65
|
-
when /claude-3-5-sonnet/ then 'claude-3-5-sonnet'
|
|
66
|
-
when /claude-3-5-haiku/ then 'claude-3-5-haiku'
|
|
67
|
-
when /claude-3-opus/ then 'claude-3-opus'
|
|
68
|
-
when /claude-3-sonnet/ then 'claude-3-sonnet'
|
|
69
|
-
when /claude-3-haiku/ then 'claude-3-haiku'
|
|
70
|
-
else 'claude-2'
|
|
71
|
-
end
|
|
72
|
-
end
|
|
73
|
-
|
|
74
|
-
def model_type(_)
|
|
75
|
-
'chat'
|
|
76
|
-
end
|
|
77
|
-
|
|
78
|
-
PRICES = {
|
|
79
|
-
'claude-3-7-sonnet': { input: 3.0, output: 15.0 },
|
|
80
|
-
'claude-3-5-sonnet': { input: 3.0, output: 15.0 },
|
|
81
|
-
'claude-3-5-haiku': { input: 0.80, output: 4.0 },
|
|
82
|
-
'claude-3-opus': { input: 15.0, output: 75.0 },
|
|
83
|
-
'claude-3-haiku': { input: 0.25, output: 1.25 },
|
|
84
|
-
'claude-2': { input: 3.0, output: 15.0 }
|
|
85
|
-
}.freeze
|
|
86
|
-
|
|
87
|
-
def default_input_price
|
|
88
|
-
3.0
|
|
89
|
-
end
|
|
90
|
-
|
|
91
|
-
def default_output_price
|
|
92
|
-
15.0
|
|
93
|
-
end
|
|
94
|
-
|
|
95
|
-
def modalities_for(model_id)
|
|
96
|
-
modalities = {
|
|
97
|
-
input: ['text'],
|
|
98
|
-
output: ['text']
|
|
99
|
-
}
|
|
100
|
-
|
|
101
|
-
unless model_id.match?(/claude-[12]/)
|
|
102
|
-
modalities[:input] << 'image'
|
|
103
|
-
modalities[:input] << 'pdf'
|
|
104
|
-
end
|
|
105
|
-
|
|
106
|
-
modalities
|
|
107
|
-
end
|
|
108
|
-
|
|
109
|
-
def capabilities_for(model_id)
|
|
110
|
-
capabilities = ['streaming']
|
|
111
|
-
|
|
112
|
-
unless model_id.match?(/claude-[12]/)
|
|
113
|
-
capabilities << 'function_calling'
|
|
114
|
-
capabilities << 'batch'
|
|
115
|
-
end
|
|
116
|
-
|
|
117
|
-
capabilities << 'structured_output' if supports_structured_output?(model_id)
|
|
118
|
-
capabilities << 'reasoning' if model_id.match?(/claude-3-7-sonnet|claude-(?:sonnet|opus|haiku)-4/)
|
|
119
|
-
capabilities << 'citations' if model_id.match?(/claude-3\.5|claude-3-7/)
|
|
120
|
-
capabilities
|
|
121
|
-
end
|
|
122
|
-
|
|
123
|
-
def pricing_for(model_id)
|
|
124
|
-
family = model_family(model_id)
|
|
125
|
-
prices = PRICES.fetch(family.to_sym, { input: default_input_price, output: default_output_price })
|
|
126
|
-
|
|
127
|
-
standard_pricing = {
|
|
128
|
-
input_per_million: prices[:input],
|
|
129
|
-
output_per_million: prices[:output]
|
|
130
|
-
}
|
|
131
|
-
|
|
132
|
-
batch_pricing = {
|
|
133
|
-
input_per_million: prices[:input] * 0.5,
|
|
134
|
-
output_per_million: prices[:output] * 0.5
|
|
135
|
-
}
|
|
136
|
-
|
|
137
|
-
if model_id.match?(/claude-3-7/)
|
|
138
|
-
standard_pricing[:reasoning_output_per_million] = prices[:output] * 2.5
|
|
139
|
-
batch_pricing[:reasoning_output_per_million] = prices[:output] * 1.25
|
|
140
|
-
end
|
|
141
|
-
|
|
142
|
-
{
|
|
143
|
-
text_tokens: {
|
|
144
|
-
standard: standard_pricing,
|
|
145
|
-
batch: batch_pricing
|
|
146
|
-
}
|
|
147
|
-
}
|
|
148
|
-
end
|
|
149
17
|
end
|
|
150
18
|
end
|
|
151
19
|
end
|
|
@@ -11,21 +11,15 @@ module RubyLLM
|
|
|
11
11
|
'v1/models'
|
|
12
12
|
end
|
|
13
13
|
|
|
14
|
-
def parse_list_models_response(response, slug,
|
|
14
|
+
def parse_list_models_response(response, slug, _capabilities)
|
|
15
15
|
Array(response.body['data']).map do |model_data|
|
|
16
16
|
model_id = model_data['id']
|
|
17
17
|
|
|
18
18
|
Model::Info.new(
|
|
19
19
|
id: model_id,
|
|
20
|
-
name: model_data['display_name'],
|
|
20
|
+
name: model_data['display_name'] || model_id,
|
|
21
21
|
provider: slug,
|
|
22
|
-
family: capabilities.model_family(model_id),
|
|
23
22
|
created_at: Time.parse(model_data['created_at']),
|
|
24
|
-
context_window: capabilities.determine_context_window(model_id),
|
|
25
|
-
max_output_tokens: capabilities.determine_max_tokens(model_id),
|
|
26
|
-
modalities: capabilities.modalities_for(model_id),
|
|
27
|
-
capabilities: capabilities.capabilities_for(model_id),
|
|
28
|
-
pricing: capabilities.pricing_for(model_id),
|
|
29
23
|
metadata: {}
|
|
30
24
|
)
|
|
31
25
|
end
|
|
@@ -53,6 +53,10 @@ module RubyLLM
|
|
|
53
53
|
end
|
|
54
54
|
|
|
55
55
|
class << self
|
|
56
|
+
def configuration_options
|
|
57
|
+
%i[bedrock_api_key bedrock_secret_key bedrock_region bedrock_session_token]
|
|
58
|
+
end
|
|
59
|
+
|
|
56
60
|
def configuration_requirements
|
|
57
61
|
%i[bedrock_api_key bedrock_secret_key bedrock_region]
|
|
58
62
|
end
|
|
@@ -3,44 +3,10 @@
|
|
|
3
3
|
module RubyLLM
|
|
4
4
|
module Providers
|
|
5
5
|
class DeepSeek
|
|
6
|
-
#
|
|
6
|
+
# Provider-level capability checks used outside the model registry.
|
|
7
7
|
module Capabilities
|
|
8
8
|
module_function
|
|
9
9
|
|
|
10
|
-
def context_window_for(model_id)
|
|
11
|
-
case model_id
|
|
12
|
-
when /deepseek-(?:chat|reasoner)/ then 64_000
|
|
13
|
-
else 32_768
|
|
14
|
-
end
|
|
15
|
-
end
|
|
16
|
-
|
|
17
|
-
def max_tokens_for(model_id)
|
|
18
|
-
case model_id
|
|
19
|
-
when /deepseek-(?:chat|reasoner)/ then 8_192
|
|
20
|
-
else 4_096
|
|
21
|
-
end
|
|
22
|
-
end
|
|
23
|
-
|
|
24
|
-
def input_price_for(model_id)
|
|
25
|
-
PRICES.dig(model_family(model_id), :input_miss) || default_input_price
|
|
26
|
-
end
|
|
27
|
-
|
|
28
|
-
def output_price_for(model_id)
|
|
29
|
-
PRICES.dig(model_family(model_id), :output) || default_output_price
|
|
30
|
-
end
|
|
31
|
-
|
|
32
|
-
def cache_hit_price_for(model_id)
|
|
33
|
-
PRICES.dig(model_family(model_id), :input_hit) || default_cache_hit_price
|
|
34
|
-
end
|
|
35
|
-
|
|
36
|
-
def supports_vision?(_model_id)
|
|
37
|
-
false
|
|
38
|
-
end
|
|
39
|
-
|
|
40
|
-
def supports_functions?(model_id)
|
|
41
|
-
model_id.match?(/deepseek-chat/)
|
|
42
|
-
end
|
|
43
|
-
|
|
44
10
|
def supports_tool_choice?(_model_id)
|
|
45
11
|
true
|
|
46
12
|
end
|
|
@@ -48,90 +14,6 @@ module RubyLLM
|
|
|
48
14
|
def supports_tool_parallel_control?(_model_id)
|
|
49
15
|
false
|
|
50
16
|
end
|
|
51
|
-
|
|
52
|
-
def supports_json_mode?(_model_id)
|
|
53
|
-
false
|
|
54
|
-
end
|
|
55
|
-
|
|
56
|
-
def format_display_name(model_id)
|
|
57
|
-
case model_id
|
|
58
|
-
when 'deepseek-chat' then 'DeepSeek V3'
|
|
59
|
-
when 'deepseek-reasoner' then 'DeepSeek R1'
|
|
60
|
-
else
|
|
61
|
-
model_id.split('-')
|
|
62
|
-
.map(&:capitalize)
|
|
63
|
-
.join(' ')
|
|
64
|
-
end
|
|
65
|
-
end
|
|
66
|
-
|
|
67
|
-
def model_type(_model_id)
|
|
68
|
-
'chat'
|
|
69
|
-
end
|
|
70
|
-
|
|
71
|
-
def model_family(model_id)
|
|
72
|
-
case model_id
|
|
73
|
-
when /deepseek-reasoner/ then :reasoner
|
|
74
|
-
else :chat
|
|
75
|
-
end
|
|
76
|
-
end
|
|
77
|
-
|
|
78
|
-
PRICES = {
|
|
79
|
-
chat: {
|
|
80
|
-
input_hit: 0.07,
|
|
81
|
-
input_miss: 0.27,
|
|
82
|
-
output: 1.10
|
|
83
|
-
},
|
|
84
|
-
reasoner: {
|
|
85
|
-
input_hit: 0.14,
|
|
86
|
-
input_miss: 0.55,
|
|
87
|
-
output: 2.19
|
|
88
|
-
}
|
|
89
|
-
}.freeze
|
|
90
|
-
|
|
91
|
-
def default_input_price
|
|
92
|
-
0.27
|
|
93
|
-
end
|
|
94
|
-
|
|
95
|
-
def default_output_price
|
|
96
|
-
1.10
|
|
97
|
-
end
|
|
98
|
-
|
|
99
|
-
def default_cache_hit_price
|
|
100
|
-
0.07
|
|
101
|
-
end
|
|
102
|
-
|
|
103
|
-
def modalities_for(_model_id)
|
|
104
|
-
{
|
|
105
|
-
input: ['text'],
|
|
106
|
-
output: ['text']
|
|
107
|
-
}
|
|
108
|
-
end
|
|
109
|
-
|
|
110
|
-
def capabilities_for(model_id)
|
|
111
|
-
capabilities = ['streaming']
|
|
112
|
-
|
|
113
|
-
capabilities << 'function_calling' if model_id.match?(/deepseek-chat/)
|
|
114
|
-
|
|
115
|
-
capabilities
|
|
116
|
-
end
|
|
117
|
-
|
|
118
|
-
def pricing_for(model_id)
|
|
119
|
-
family = model_family(model_id)
|
|
120
|
-
prices = PRICES.fetch(family, { input_miss: default_input_price, output: default_output_price })
|
|
121
|
-
|
|
122
|
-
standard_pricing = {
|
|
123
|
-
input_per_million: prices[:input_miss],
|
|
124
|
-
output_per_million: prices[:output]
|
|
125
|
-
}
|
|
126
|
-
|
|
127
|
-
standard_pricing[:cached_input_per_million] = prices[:input_hit] if prices[:input_hit]
|
|
128
|
-
|
|
129
|
-
{
|
|
130
|
-
text_tokens: {
|
|
131
|
-
standard: standard_pricing
|
|
132
|
-
}
|
|
133
|
-
}
|
|
134
|
-
end
|
|
135
17
|
end
|
|
136
18
|
end
|
|
137
19
|
end
|