dify_llm 1.9.0 → 1.9.2

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 75dbb53612d3fa2c1089038bcf48fbbc0fe9425d37ffd8fccdfa56337daf97af
4
- data.tar.gz: 316d3ef004a7387a6e723a02f8ab09729b167097127f9cb85ce5a864e6e4ef1e
3
+ metadata.gz: 8b0ccd75734d4873be1de4cba718299f0c82442c0ecffda9d4e990b9c81823fe
4
+ data.tar.gz: 5350541b348132f81e812daa4eed4c60e71e9c6203631dc64d6f711dbcea1aa5
5
5
  SHA512:
6
- metadata.gz: bca45bf0d49f6e98e9ea00cf2e760537fbff5f861394080f8dec8baa634784289f23779476eedbda5c9d11e4323e2a67f6eadc84144c18cd4adc7d09e3b9cfe7
7
- data.tar.gz: a12a868701ae4e70f6f397de290d3bc018da91993950366d956fd8d60f0c37cc8ef89f882a680db396336258107e032f881817224668b81d9d65b3f53c1f44d9
6
+ metadata.gz: 01b39c3b4098d06b6dbb89bba11485a0951e608a6910157834e40440ce099a05f2004dd022f269fe5b11dce6bececd5e612836d01180eb3f8c642cef60eb0ec9
7
+ data.tar.gz: eaa24c9d5c25adf9654d7108b290a80d5152dc1fd8e9f3d6da8672595ad4888e66eb41ecb47a3ceb2040bcf3f8fde13f1e30a93557a11d6d6e087ef238e649b3
@@ -52,8 +52,10 @@ module RubyLLM
52
52
  def acts_as_chat_declaration
53
53
  params = []
54
54
 
55
- add_association_params(params, :messages, message_table_name, message_model_name, plural: true)
56
- add_association_params(params, :model, model_table_name, model_model_name)
55
+ add_association_params(params, :messages, message_table_name, message_model_name,
56
+ owner_table: chat_table_name, plural: true)
57
+ add_association_params(params, :model, model_table_name, model_model_name,
58
+ owner_table: chat_table_name)
57
59
 
58
60
  "acts_as_chat#{" #{params.join(', ')}" if params.any?}"
59
61
  end
@@ -61,9 +63,12 @@ module RubyLLM
61
63
  def acts_as_message_declaration
62
64
  params = []
63
65
 
64
- add_association_params(params, :chat, chat_table_name, chat_model_name)
65
- add_association_params(params, :tool_calls, tool_call_table_name, tool_call_model_name, plural: true)
66
- add_association_params(params, :model, model_table_name, model_model_name)
66
+ add_association_params(params, :chat, chat_table_name, chat_model_name,
67
+ owner_table: message_table_name)
68
+ add_association_params(params, :tool_calls, tool_call_table_name, tool_call_model_name,
69
+ owner_table: message_table_name, plural: true)
70
+ add_association_params(params, :model, model_table_name, model_model_name,
71
+ owner_table: message_table_name)
67
72
 
68
73
  "acts_as_message#{" #{params.join(', ')}" if params.any?}"
69
74
  end
@@ -71,7 +76,8 @@ module RubyLLM
71
76
  def acts_as_model_declaration
72
77
  params = []
73
78
 
74
- add_association_params(params, :chats, chat_table_name, chat_model_name, plural: true)
79
+ add_association_params(params, :chats, chat_table_name, chat_model_name,
80
+ owner_table: model_table_name, plural: true)
75
81
 
76
82
  "acts_as_model#{" #{params.join(', ')}" if params.any?}"
77
83
  end
@@ -79,7 +85,8 @@ module RubyLLM
79
85
  def acts_as_tool_call_declaration
80
86
  params = []
81
87
 
82
- add_association_params(params, :message, message_table_name, message_model_name)
88
+ add_association_params(params, :message, message_table_name, message_model_name,
89
+ owner_table: tool_call_table_name)
83
90
 
84
91
  "acts_as_tool_call#{" #{params.join(', ')}" if params.any?}"
85
92
  end
@@ -120,6 +127,12 @@ module RubyLLM
120
127
  false
121
128
  end
122
129
 
130
+ def mysql?
131
+ ::ActiveRecord::Base.connection.adapter_name.downcase.include?('mysql')
132
+ rescue StandardError
133
+ false
134
+ end
135
+
123
136
  def table_exists?(table_name)
124
137
  ::ActiveRecord::Base.connection.table_exists?(table_name)
125
138
  rescue StandardError
@@ -128,13 +141,21 @@ module RubyLLM
128
141
 
129
142
  private
130
143
 
131
- def add_association_params(params, default_assoc, table_name, model_name, plural: false)
144
+ def add_association_params(params, default_assoc, table_name, model_name, owner_table:, plural: false) # rubocop:disable Metrics/ParameterLists
132
145
  assoc = plural ? table_name.to_sym : table_name.singularize.to_sym
133
146
 
134
- return if assoc == default_assoc
147
+ default_foreign_key = "#{default_assoc}_id"
148
+ # has_many/has_one: foreign key is on the associated table pointing back to owner
149
+ # belongs_to: foreign key is on the owner table pointing to associated table
150
+ foreign_key = if plural || default_assoc.to_s.pluralize == default_assoc.to_s # has_many or has_one
151
+ "#{owner_table.singularize}_id"
152
+ else # belongs_to
153
+ "#{table_name.singularize}_id"
154
+ end
135
155
 
136
- params << "#{default_assoc}: :#{assoc}"
156
+ params << "#{default_assoc}: :#{assoc}" if assoc != default_assoc
137
157
  params << "#{default_assoc.to_s.singularize}_class: '#{model_name}'" if model_name != assoc.to_s.classify
158
+ params << "#{default_assoc}_foreign_key: :#{foreign_key}" if foreign_key != default_foreign_key
138
159
  end
139
160
 
140
161
  # Convert namespaced model names to proper table names
@@ -14,6 +14,11 @@ class Create<%= model_model_name.gsub('::', '').pluralize %> < ActiveRecord::Mig
14
14
  t.jsonb :capabilities, default: []
15
15
  t.jsonb :pricing, default: {}
16
16
  t.jsonb :metadata, default: {}
17
+ <% elsif mysql? %>
18
+ t.json :modalities
19
+ t.json :capabilities
20
+ t.json :pricing
21
+ t.json :metadata
17
22
  <% else %>
18
23
  t.json :modalities, default: {}
19
24
  t.json :capabilities, default: []
@@ -4,7 +4,13 @@ class Create<%= tool_call_model_name.gsub('::', '').pluralize %> < ActiveRecord:
4
4
  create_table :<%= tool_call_table_name %> do |t|
5
5
  t.string :tool_call_id, null: false
6
6
  t.string :name, null: false
7
- t.<%= postgresql? ? 'jsonb' : 'json' %> :arguments, default: {}
7
+ <% if postgresql? %>
8
+ t.jsonb :arguments, default: {}
9
+ <% elsif mysql? %>
10
+ t.json :arguments
11
+ <% else %>
12
+ t.json :arguments, default: {}
13
+ <% end %>
8
14
  t.timestamps
9
15
  end
10
16
 
@@ -1,4 +1,4 @@
1
- class MigrateToRubyLLMModelReferences < ActiveRecord::Migration<%= migration_version %>
1
+ class MigrateToRubyLlmModelReferences < ActiveRecord::Migration<%= migration_version %>
2
2
  def up
3
3
  model_class = <%= model_model_name %>
4
4
  chat_class = <%= chat_model_name %>
@@ -31,8 +31,8 @@ module RubyLLM
31
31
  end
32
32
 
33
33
  class_methods do # rubocop:disable Metrics/BlockLength
34
- def acts_as_chat(messages: :messages, message_class: nil,
35
- model: :model, model_class: nil)
34
+ def acts_as_chat(messages: :messages, message_class: nil, messages_foreign_key: nil, # rubocop:disable Metrics/ParameterLists
35
+ model: :model, model_class: nil, model_foreign_key: nil)
36
36
  include RubyLLM::ActiveRecord::ChatMethods
37
37
 
38
38
  class_attribute :messages_association_name, :model_association_name, :message_class, :model_class
@@ -45,12 +45,12 @@ module RubyLLM
45
45
  has_many messages,
46
46
  -> { order(created_at: :asc) },
47
47
  class_name: self.message_class,
48
- foreign_key: ActiveSupport::Inflector.foreign_key(table_name.singularize),
48
+ foreign_key: messages_foreign_key,
49
49
  dependent: :destroy
50
50
 
51
51
  belongs_to model,
52
52
  class_name: self.model_class,
53
- foreign_key: ActiveSupport::Inflector.foreign_key(model.to_s.singularize),
53
+ foreign_key: model_foreign_key,
54
54
  optional: true
55
55
 
56
56
  delegate :add_message, to: :to_llm
@@ -68,7 +68,7 @@ module RubyLLM
68
68
  end
69
69
  end
70
70
 
71
- def acts_as_model(chats: :chats, chat_class: nil)
71
+ def acts_as_model(chats: :chats, chat_class: nil, chats_foreign_key: nil)
72
72
  include RubyLLM::ActiveRecord::ModelMethods
73
73
 
74
74
  class_attribute :chats_association_name, :chat_class
@@ -80,18 +80,16 @@ module RubyLLM
80
80
  validates :provider, presence: true
81
81
  validates :name, presence: true
82
82
 
83
- has_many chats,
84
- class_name: self.chat_class,
85
- foreign_key: ActiveSupport::Inflector.foreign_key(table_name.singularize)
83
+ has_many chats, class_name: self.chat_class, foreign_key: chats_foreign_key
86
84
 
87
85
  define_method :chats_association do
88
86
  send(chats_association_name)
89
87
  end
90
88
  end
91
89
 
92
- def acts_as_message(chat: :chat, chat_class: nil, touch_chat: false, # rubocop:disable Metrics/ParameterLists
93
- tool_calls: :tool_calls, tool_call_class: nil,
94
- model: :model, model_class: nil)
90
+ def acts_as_message(chat: :chat, chat_class: nil, chat_foreign_key: nil, touch_chat: false, # rubocop:disable Metrics/ParameterLists
91
+ tool_calls: :tool_calls, tool_call_class: nil, tool_calls_foreign_key: nil,
92
+ model: :model, model_class: nil, model_foreign_key: nil)
95
93
  include RubyLLM::ActiveRecord::MessageMethods
96
94
 
97
95
  class_attribute :chat_association_name, :tool_calls_association_name, :model_association_name,
@@ -106,12 +104,12 @@ module RubyLLM
106
104
 
107
105
  belongs_to chat,
108
106
  class_name: self.chat_class,
109
- foreign_key: ActiveSupport::Inflector.foreign_key(chat.to_s.singularize),
107
+ foreign_key: chat_foreign_key,
110
108
  touch: touch_chat
111
109
 
112
110
  has_many tool_calls,
113
111
  class_name: self.tool_call_class,
114
- foreign_key: ActiveSupport::Inflector.foreign_key(table_name.singularize),
112
+ foreign_key: tool_calls_foreign_key,
115
113
  dependent: :destroy
116
114
 
117
115
  belongs_to :parent_tool_call,
@@ -126,7 +124,7 @@ module RubyLLM
126
124
 
127
125
  belongs_to model,
128
126
  class_name: self.model_class,
129
- foreign_key: ActiveSupport::Inflector.foreign_key(model.to_s.singularize),
127
+ foreign_key: model_foreign_key,
130
128
  optional: true
131
129
 
132
130
  delegate :tool_call?, :tool_result?, to: :to_llm
@@ -144,8 +142,8 @@ module RubyLLM
144
142
  end
145
143
  end
146
144
 
147
- def acts_as_tool_call(message: :message, message_class: nil,
148
- result: :result, result_class: nil)
145
+ def acts_as_tool_call(message: :message, message_class: nil, message_foreign_key: nil, # rubocop:disable Metrics/ParameterLists
146
+ result: :result, result_class: nil, result_foreign_key: nil)
149
147
  class_attribute :message_association_name, :result_association_name, :message_class, :result_class
150
148
 
151
149
  self.message_association_name = message
@@ -155,11 +153,11 @@ module RubyLLM
155
153
 
156
154
  belongs_to message,
157
155
  class_name: self.message_class,
158
- foreign_key: ActiveSupport::Inflector.foreign_key(message.to_s.singularize)
156
+ foreign_key: message_foreign_key
159
157
 
160
158
  has_one result,
161
159
  class_name: self.result_class,
162
- foreign_key: ActiveSupport::Inflector.foreign_key(table_name.singularize),
160
+ foreign_key: result_foreign_key,
163
161
  dependent: :nullify
164
162
 
165
163
  define_method :message_association do
@@ -19,7 +19,7 @@
19
19
  "claude-3-7-sonnet": {
20
20
  "anthropic": "claude-3-7-sonnet-20250219",
21
21
  "openrouter": "anthropic/claude-3.7-sonnet",
22
- "bedrock": "us.anthropic.claude-3-7-sonnet-20250219-v1:0"
22
+ "bedrock": "anthropic.claude-3-7-sonnet-20250219-v1:0"
23
23
  },
24
24
  "claude-3-7-sonnet-latest": {
25
25
  "anthropic": "claude-3-7-sonnet-latest"
@@ -31,21 +31,21 @@
31
31
  },
32
32
  "claude-3-opus": {
33
33
  "anthropic": "claude-3-opus-20240229",
34
- "openrouter": "anthropic/claude-3-opus",
35
34
  "bedrock": "anthropic.claude-3-opus-20240229-v1:0:200k"
36
35
  },
37
36
  "claude-3-sonnet": {
38
- "bedrock": "anthropic.claude-3-sonnet-20240229-v1:0"
37
+ "anthropic": "claude-3-sonnet-20240229",
38
+ "bedrock": "anthropic.claude-3-sonnet-20240229-v1:0:200k"
39
39
  },
40
40
  "claude-haiku-4-5": {
41
41
  "anthropic": "claude-haiku-4-5-20251001",
42
42
  "openrouter": "anthropic/claude-haiku-4.5",
43
- "bedrock": "us.anthropic.claude-haiku-4-5-20251001-v1:0"
43
+ "bedrock": "anthropic.claude-haiku-4-5-20251001-v1:0"
44
44
  },
45
45
  "claude-opus-4": {
46
46
  "anthropic": "claude-opus-4-20250514",
47
47
  "openrouter": "anthropic/claude-opus-4",
48
- "bedrock": "us.anthropic.claude-opus-4-1-20250805-v1:0"
48
+ "bedrock": "anthropic.claude-opus-4-1-20250805-v1:0"
49
49
  },
50
50
  "claude-opus-4-0": {
51
51
  "anthropic": "claude-opus-4-0"
@@ -53,12 +53,17 @@
53
53
  "claude-opus-4-1": {
54
54
  "anthropic": "claude-opus-4-1-20250805",
55
55
  "openrouter": "anthropic/claude-opus-4.1",
56
- "bedrock": "us.anthropic.claude-opus-4-1-20250805-v1:0"
56
+ "bedrock": "anthropic.claude-opus-4-1-20250805-v1:0"
57
+ },
58
+ "claude-opus-4-5": {
59
+ "anthropic": "claude-opus-4-5-20251101",
60
+ "openrouter": "anthropic/claude-opus-4.5",
61
+ "bedrock": "anthropic.claude-opus-4-5-20251101-v1:0"
57
62
  },
58
63
  "claude-sonnet-4": {
59
64
  "anthropic": "claude-sonnet-4-20250514",
60
65
  "openrouter": "anthropic/claude-sonnet-4",
61
- "bedrock": "us.anthropic.claude-sonnet-4-20250514-v1:0"
66
+ "bedrock": "anthropic.claude-sonnet-4-20250514-v1:0"
62
67
  },
63
68
  "claude-sonnet-4-0": {
64
69
  "anthropic": "claude-sonnet-4-0"
@@ -66,12 +71,24 @@
66
71
  "claude-sonnet-4-5": {
67
72
  "anthropic": "claude-sonnet-4-5-20250929",
68
73
  "openrouter": "anthropic/claude-sonnet-4.5",
69
- "bedrock": "us.anthropic.claude-sonnet-4-5-20250929-v1:0"
74
+ "bedrock": "anthropic.claude-sonnet-4-5-20250929-v1:0"
70
75
  },
71
76
  "deepseek-chat": {
72
77
  "deepseek": "deepseek-chat",
73
78
  "openrouter": "deepseek/deepseek-chat"
74
79
  },
80
+ "gemini-1.5-flash": {
81
+ "gemini": "gemini-1.5-flash",
82
+ "vertexai": "gemini-1.5-flash"
83
+ },
84
+ "gemini-1.5-flash-8b": {
85
+ "gemini": "gemini-1.5-flash-8b",
86
+ "vertexai": "gemini-1.5-flash-8b"
87
+ },
88
+ "gemini-1.5-pro": {
89
+ "gemini": "gemini-1.5-pro",
90
+ "vertexai": "gemini-1.5-pro"
91
+ },
75
92
  "gemini-2.0-flash": {
76
93
  "gemini": "gemini-2.0-flash",
77
94
  "vertexai": "gemini-2.0-flash"
@@ -85,6 +102,10 @@
85
102
  "gemini": "gemini-2.0-flash-exp",
86
103
  "vertexai": "gemini-2.0-flash-exp"
87
104
  },
105
+ "gemini-2.0-flash-lite": {
106
+ "gemini": "gemini-2.0-flash-lite",
107
+ "vertexai": "gemini-2.0-flash-lite"
108
+ },
88
109
  "gemini-2.0-flash-lite-001": {
89
110
  "gemini": "gemini-2.0-flash-lite-001",
90
111
  "openrouter": "google/gemini-2.0-flash-lite-001",
@@ -110,15 +131,25 @@
110
131
  },
111
132
  "gemini-2.5-flash-lite-preview-06-17": {
112
133
  "gemini": "gemini-2.5-flash-lite-preview-06-17",
113
- "openrouter": "google/gemini-2.5-flash-lite-preview-06-17"
134
+ "vertexai": "gemini-2.5-flash-lite-preview-06-17"
114
135
  },
115
136
  "gemini-2.5-flash-lite-preview-09-2025": {
116
137
  "gemini": "gemini-2.5-flash-lite-preview-09-2025",
117
- "openrouter": "google/gemini-2.5-flash-lite-preview-09-2025"
138
+ "openrouter": "google/gemini-2.5-flash-lite-preview-09-2025",
139
+ "vertexai": "gemini-2.5-flash-lite-preview-09-2025"
140
+ },
141
+ "gemini-2.5-flash-preview-04-17": {
142
+ "gemini": "gemini-2.5-flash-preview-04-17",
143
+ "vertexai": "gemini-2.5-flash-preview-04-17"
144
+ },
145
+ "gemini-2.5-flash-preview-05-20": {
146
+ "gemini": "gemini-2.5-flash-preview-05-20",
147
+ "vertexai": "gemini-2.5-flash-preview-05-20"
118
148
  },
119
149
  "gemini-2.5-flash-preview-09-2025": {
120
150
  "gemini": "gemini-2.5-flash-preview-09-2025",
121
- "openrouter": "google/gemini-2.5-flash-preview-09-2025"
151
+ "openrouter": "google/gemini-2.5-flash-preview-09-2025",
152
+ "vertexai": "gemini-2.5-flash-preview-09-2025"
122
153
  },
123
154
  "gemini-2.5-pro": {
124
155
  "gemini": "gemini-2.5-pro",
@@ -127,7 +158,27 @@
127
158
  },
128
159
  "gemini-2.5-pro-preview-05-06": {
129
160
  "gemini": "gemini-2.5-pro-preview-05-06",
130
- "openrouter": "google/gemini-2.5-pro-preview-05-06"
161
+ "openrouter": "google/gemini-2.5-pro-preview-05-06",
162
+ "vertexai": "gemini-2.5-pro-preview-05-06"
163
+ },
164
+ "gemini-2.5-pro-preview-06-05": {
165
+ "gemini": "gemini-2.5-pro-preview-06-05",
166
+ "openrouter": "google/gemini-2.5-pro-preview-06-05",
167
+ "vertexai": "gemini-2.5-pro-preview-06-05"
168
+ },
169
+ "gemini-3-flash-preview": {
170
+ "gemini": "gemini-3-flash-preview",
171
+ "openrouter": "google/gemini-3-flash-preview",
172
+ "vertexai": "gemini-3-flash-preview"
173
+ },
174
+ "gemini-3-pro-image-preview": {
175
+ "gemini": "gemini-3-pro-image-preview",
176
+ "openrouter": "google/gemini-3-pro-image-preview"
177
+ },
178
+ "gemini-3-pro-preview": {
179
+ "gemini": "gemini-3-pro-preview",
180
+ "openrouter": "google/gemini-3-pro-preview",
181
+ "vertexai": "gemini-3-pro-preview"
131
182
  },
132
183
  "gemini-embedding-001": {
133
184
  "gemini": "gemini-embedding-001",
@@ -137,6 +188,14 @@
137
188
  "gemini": "gemini-exp-1206",
138
189
  "vertexai": "gemini-exp-1206"
139
190
  },
191
+ "gemini-flash": {
192
+ "gemini": "gemini-flash-latest",
193
+ "vertexai": "gemini-flash-latest"
194
+ },
195
+ "gemini-flash-lite": {
196
+ "gemini": "gemini-flash-lite-latest",
197
+ "vertexai": "gemini-flash-lite-latest"
198
+ },
140
199
  "gemma-3-12b-it": {
141
200
  "gemini": "gemma-3-12b-it",
142
201
  "openrouter": "google/gemma-3-12b-it"
@@ -249,30 +308,50 @@
249
308
  "openai": "gpt-5-pro",
250
309
  "openrouter": "openai/gpt-5-pro"
251
310
  },
252
- "gpt-oss-120b": {
253
- "openai": "gpt-oss-120b",
254
- "openrouter": "openai/gpt-oss-120b"
311
+ "gpt-5.1": {
312
+ "openai": "gpt-5.1",
313
+ "openrouter": "openai/gpt-5.1"
314
+ },
315
+ "gpt-5.1-codex": {
316
+ "openai": "gpt-5.1-codex",
317
+ "openrouter": "openai/gpt-5.1-codex"
318
+ },
319
+ "gpt-5.1-codex-max": {
320
+ "openai": "gpt-5.1-codex-max",
321
+ "openrouter": "openai/gpt-5.1-codex-max"
322
+ },
323
+ "gpt-5.1-codex-mini": {
324
+ "openai": "gpt-5.1-codex-mini",
325
+ "openrouter": "openai/gpt-5.1-codex-mini"
326
+ },
327
+ "gpt-5.2": {
328
+ "openai": "gpt-5.2",
329
+ "openrouter": "openai/gpt-5.2"
255
330
  },
256
- "gpt-oss-20b": {
257
- "openai": "gpt-oss-20b",
258
- "openrouter": "openai/gpt-oss-20b"
331
+ "gpt-5.2-chat": {
332
+ "openai": "gpt-5.2-chat-latest",
333
+ "openrouter": "openai/gpt-5.2-chat-latest"
334
+ },
335
+ "gpt-5.2-pro": {
336
+ "openai": "gpt-5.2-pro",
337
+ "openrouter": "openai/gpt-5.2-pro"
338
+ },
339
+ "imagen-4.0-fast-generate-001": {
340
+ "gemini": "imagen-4.0-fast-generate-001",
341
+ "vertexai": "imagen-4.0-fast-generate-001"
259
342
  },
260
343
  "imagen-4.0-generate-001": {
261
344
  "gemini": "imagen-4.0-generate-001",
262
345
  "vertexai": "imagen-4.0-generate-001"
263
346
  },
347
+ "imagen-4.0-ultra-generate-001": {
348
+ "gemini": "imagen-4.0-ultra-generate-001",
349
+ "vertexai": "imagen-4.0-ultra-generate-001"
350
+ },
264
351
  "o1": {
265
352
  "openai": "o1",
266
353
  "openrouter": "openai/o1"
267
354
  },
268
- "o1-mini": {
269
- "openai": "o1-mini",
270
- "openrouter": "openai/o1-mini"
271
- },
272
- "o1-mini-2024-09-12": {
273
- "openai": "o1-mini-2024-09-12",
274
- "openrouter": "openai/o1-mini-2024-09-12"
275
- },
276
355
  "o1-pro": {
277
356
  "openai": "o1-pro",
278
357
  "openrouter": "openai/o1-pro"
@@ -7,19 +7,8 @@ module RubyLLM
7
7
 
8
8
  def initialize(source, filename: nil)
9
9
  @source = source
10
- if url?
11
- @source = URI source
12
- @filename = filename || File.basename(@source.path).to_s
13
- elsif uuid?
14
- @upload_file_id = source
15
- elsif path?
16
- @source = Pathname.new source
17
- @filename = filename || @source.basename.to_s
18
- elsif active_storage?
19
- @filename = filename || extract_filename_from_active_storage
20
- else
21
- @filename = filename
22
- end
10
+ @source = source_type_cast
11
+ @filename = filename || source_filename
23
12
 
24
13
  determine_mime_type if @upload_file_id.nil?
25
14
  end
@@ -29,7 +18,11 @@ module RubyLLM
29
18
  end
30
19
 
31
20
  def path?
32
- @source.is_a?(Pathname) || (@source.is_a?(String) && !url?)
21
+ return true if @source.is_a?(Pathname)
22
+ return false unless @source.is_a?(String)
23
+ return false if url? || uuid?
24
+
25
+ true
33
26
  end
34
27
 
35
28
  def io_like?
@@ -173,6 +166,42 @@ module RubyLLM
173
166
  end
174
167
  end
175
168
 
169
+ def source_type_cast
170
+ if url?
171
+ URI(@source)
172
+ elsif uuid?
173
+ @upload_file_id = @source
174
+ elsif path?
175
+ Pathname.new(@source)
176
+ else
177
+ @source
178
+ end
179
+ end
180
+
181
+ def source_filename
182
+ return 'attachment' unless @upload_file_id.nil?
183
+
184
+ if url?
185
+ File.basename(@source.path).to_s
186
+ elsif path?
187
+ @source.basename.to_s
188
+ elsif io_like?
189
+ extract_filename_from_io
190
+ elsif active_storage?
191
+ extract_filename_from_active_storage
192
+ end
193
+ end
194
+
195
+ def extract_filename_from_io
196
+ if defined?(ActionDispatch::Http::UploadedFile) && @source.is_a?(ActionDispatch::Http::UploadedFile)
197
+ @source.original_filename.to_s
198
+ elsif @source.respond_to?(:path)
199
+ File.basename(@source.path).to_s
200
+ else
201
+ 'attachment'
202
+ end
203
+ end
204
+
176
205
  def extract_filename_from_active_storage # rubocop:disable Metrics/PerceivedComplexity
177
206
  return 'attachment' unless defined?(ActiveStorage)
178
207