lfx-nightly 0.2.0.dev41__py3-none-any.whl → 0.3.0.dev3__py3-none-any.whl

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.
Files changed (98) hide show
  1. lfx/__main__.py +137 -6
  2. lfx/_assets/component_index.json +1 -1
  3. lfx/base/agents/agent.py +10 -6
  4. lfx/base/agents/altk_base_agent.py +5 -3
  5. lfx/base/agents/altk_tool_wrappers.py +1 -1
  6. lfx/base/agents/events.py +1 -1
  7. lfx/base/agents/utils.py +4 -0
  8. lfx/base/composio/composio_base.py +78 -41
  9. lfx/base/data/cloud_storage_utils.py +156 -0
  10. lfx/base/data/docling_utils.py +130 -55
  11. lfx/base/datastax/astradb_base.py +75 -64
  12. lfx/base/embeddings/embeddings_class.py +113 -0
  13. lfx/base/models/__init__.py +11 -1
  14. lfx/base/models/google_generative_ai_constants.py +33 -9
  15. lfx/base/models/model_metadata.py +6 -0
  16. lfx/base/models/ollama_constants.py +196 -30
  17. lfx/base/models/openai_constants.py +37 -10
  18. lfx/base/models/unified_models.py +1123 -0
  19. lfx/base/models/watsonx_constants.py +43 -4
  20. lfx/base/prompts/api_utils.py +40 -5
  21. lfx/base/tools/component_tool.py +2 -9
  22. lfx/cli/__init__.py +10 -2
  23. lfx/cli/commands.py +3 -0
  24. lfx/cli/run.py +65 -409
  25. lfx/cli/script_loader.py +18 -7
  26. lfx/cli/validation.py +6 -3
  27. lfx/components/__init__.py +0 -3
  28. lfx/components/composio/github_composio.py +1 -1
  29. lfx/components/cuga/cuga_agent.py +39 -27
  30. lfx/components/data_source/api_request.py +4 -2
  31. lfx/components/datastax/astradb_assistant_manager.py +4 -2
  32. lfx/components/docling/__init__.py +45 -11
  33. lfx/components/docling/docling_inline.py +39 -49
  34. lfx/components/docling/docling_remote.py +1 -0
  35. lfx/components/elastic/opensearch_multimodal.py +1733 -0
  36. lfx/components/files_and_knowledge/file.py +384 -36
  37. lfx/components/files_and_knowledge/ingestion.py +8 -0
  38. lfx/components/files_and_knowledge/retrieval.py +10 -0
  39. lfx/components/files_and_knowledge/save_file.py +91 -88
  40. lfx/components/langchain_utilities/ibm_granite_handler.py +211 -0
  41. lfx/components/langchain_utilities/tool_calling.py +37 -6
  42. lfx/components/llm_operations/batch_run.py +64 -18
  43. lfx/components/llm_operations/lambda_filter.py +213 -101
  44. lfx/components/llm_operations/llm_conditional_router.py +39 -7
  45. lfx/components/llm_operations/structured_output.py +38 -12
  46. lfx/components/models/__init__.py +16 -74
  47. lfx/components/models_and_agents/agent.py +51 -203
  48. lfx/components/models_and_agents/embedding_model.py +171 -255
  49. lfx/components/models_and_agents/language_model.py +54 -318
  50. lfx/components/models_and_agents/mcp_component.py +96 -10
  51. lfx/components/models_and_agents/prompt.py +105 -18
  52. lfx/components/ollama/ollama_embeddings.py +111 -29
  53. lfx/components/openai/openai_chat_model.py +1 -1
  54. lfx/components/processing/text_operations.py +580 -0
  55. lfx/components/vllm/__init__.py +37 -0
  56. lfx/components/vllm/vllm.py +141 -0
  57. lfx/components/vllm/vllm_embeddings.py +110 -0
  58. lfx/custom/custom_component/component.py +65 -10
  59. lfx/custom/custom_component/custom_component.py +8 -6
  60. lfx/events/observability/__init__.py +0 -0
  61. lfx/events/observability/lifecycle_events.py +111 -0
  62. lfx/field_typing/__init__.py +57 -58
  63. lfx/graph/graph/base.py +40 -1
  64. lfx/graph/utils.py +109 -30
  65. lfx/graph/vertex/base.py +75 -23
  66. lfx/graph/vertex/vertex_types.py +0 -5
  67. lfx/inputs/__init__.py +2 -0
  68. lfx/inputs/input_mixin.py +55 -0
  69. lfx/inputs/inputs.py +120 -0
  70. lfx/interface/components.py +24 -7
  71. lfx/interface/initialize/loading.py +42 -12
  72. lfx/io/__init__.py +2 -0
  73. lfx/run/__init__.py +5 -0
  74. lfx/run/base.py +464 -0
  75. lfx/schema/__init__.py +50 -0
  76. lfx/schema/data.py +1 -1
  77. lfx/schema/image.py +26 -7
  78. lfx/schema/message.py +104 -11
  79. lfx/schema/workflow.py +171 -0
  80. lfx/services/deps.py +12 -0
  81. lfx/services/interfaces.py +43 -1
  82. lfx/services/mcp_composer/service.py +7 -1
  83. lfx/services/schema.py +1 -0
  84. lfx/services/settings/auth.py +95 -4
  85. lfx/services/settings/base.py +11 -1
  86. lfx/services/settings/constants.py +2 -0
  87. lfx/services/settings/utils.py +82 -0
  88. lfx/services/storage/local.py +13 -8
  89. lfx/services/transaction/__init__.py +5 -0
  90. lfx/services/transaction/service.py +35 -0
  91. lfx/tests/unit/components/__init__.py +0 -0
  92. lfx/utils/constants.py +2 -0
  93. lfx/utils/mustache_security.py +79 -0
  94. lfx/utils/validate_cloud.py +81 -3
  95. {lfx_nightly-0.2.0.dev41.dist-info → lfx_nightly-0.3.0.dev3.dist-info}/METADATA +7 -2
  96. {lfx_nightly-0.2.0.dev41.dist-info → lfx_nightly-0.3.0.dev3.dist-info}/RECORD +98 -80
  97. {lfx_nightly-0.2.0.dev41.dist-info → lfx_nightly-0.3.0.dev3.dist-info}/WHEEL +0 -0
  98. {lfx_nightly-0.2.0.dev41.dist-info → lfx_nightly-0.3.0.dev3.dist-info}/entry_points.txt +0 -0
@@ -1,16 +1,13 @@
1
1
  from typing import Any
2
2
 
3
- import requests
4
- from ibm_watsonx_ai.metanames import EmbedTextParamsMetaNames
5
- from langchain_openai import OpenAIEmbeddings
6
-
7
3
  from lfx.base.embeddings.model import LCEmbeddingsModel
8
- from lfx.base.models.model_utils import get_ollama_models, is_valid_ollama_url
9
- from lfx.base.models.openai_constants import OPENAI_EMBEDDING_MODEL_NAMES
10
- from lfx.base.models.watsonx_constants import (
11
- IBM_WATSONX_URLS,
12
- WATSONX_EMBEDDING_MODEL_NAMES,
4
+ from lfx.base.models.unified_models import (
5
+ get_api_key_for_provider,
6
+ get_embedding_classes,
7
+ get_embedding_model_options,
8
+ update_model_options_in_build_config,
13
9
  )
10
+ from lfx.base.models.watsonx_constants import IBM_WATSONX_URLS
14
11
  from lfx.field_typing import Embeddings
15
12
  from lfx.io import (
16
13
  BoolInput,
@@ -19,19 +16,9 @@ from lfx.io import (
19
16
  FloatInput,
20
17
  IntInput,
21
18
  MessageTextInput,
19
+ ModelInput,
22
20
  SecretStrInput,
23
21
  )
24
- from lfx.log.logger import logger
25
- from lfx.schema.dotdict import dotdict
26
- from lfx.utils.util import transform_localhost_url
27
-
28
- # Ollama API constants
29
- HTTP_STATUS_OK = 200
30
- JSON_MODELS_KEY = "models"
31
- JSON_NAME_KEY = "name"
32
- JSON_CAPABILITIES_KEY = "capabilities"
33
- DESIRED_CAPABILITY = "embedding"
34
- DEFAULT_OLLAMA_URL = "http://localhost:11434"
35
22
 
36
23
 
37
24
  class EmbeddingModelComponent(LCEmbeddingsModel):
@@ -42,15 +29,51 @@ class EmbeddingModelComponent(LCEmbeddingsModel):
42
29
  name = "EmbeddingModel"
43
30
  category = "models"
44
31
 
32
+ def update_build_config(self, build_config: dict, field_value: str, field_name: str | None = None):
33
+ """Dynamically update build config with user-filtered model options."""
34
+ # Update model options
35
+ build_config = update_model_options_in_build_config(
36
+ component=self,
37
+ build_config=build_config,
38
+ cache_key_prefix="embedding_model_options",
39
+ get_options_func=get_embedding_model_options,
40
+ field_name=field_name,
41
+ field_value=field_value,
42
+ )
43
+
44
+ # Show/hide provider-specific fields based on selected model
45
+ if field_name == "model" and isinstance(field_value, list) and len(field_value) > 0:
46
+ selected_model = field_value[0]
47
+ provider = selected_model.get("provider", "")
48
+
49
+ # Show/hide watsonx fields
50
+ is_watsonx = provider == "IBM WatsonX"
51
+ build_config["base_url_ibm_watsonx"]["show"] = is_watsonx
52
+ build_config["project_id"]["show"] = is_watsonx
53
+ build_config["truncate_input_tokens"]["show"] = is_watsonx
54
+ build_config["input_text"]["show"] = is_watsonx
55
+ if is_watsonx:
56
+ build_config["base_url_ibm_watsonx"]["required"] = True
57
+ build_config["project_id"]["required"] = True
58
+
59
+ return build_config
60
+
45
61
  inputs = [
46
- DropdownInput(
47
- name="provider",
48
- display_name="Model Provider",
49
- options=["OpenAI", "Ollama", "IBM watsonx.ai"],
50
- value="OpenAI",
51
- info="Select the embedding model provider",
62
+ ModelInput(
63
+ name="model",
64
+ display_name="Embedding Model",
65
+ info="Select your model provider",
66
+ real_time_refresh=True,
67
+ required=True,
68
+ model_type="embedding",
69
+ input_types=["Embeddings"], # Override default to accept Embeddings instead of LanguageModel
70
+ ),
71
+ SecretStrInput(
72
+ name="api_key",
73
+ display_name="API Key",
74
+ info="Model Provider API key",
52
75
  real_time_refresh=True,
53
- options_metadata=[{"icon": "OpenAI"}, {"icon": "Ollama"}, {"icon": "WatsonxAI"}],
76
+ advanced=True,
54
77
  ),
55
78
  MessageTextInput(
56
79
  name="api_base",
@@ -58,15 +81,7 @@ class EmbeddingModelComponent(LCEmbeddingsModel):
58
81
  info="Base URL for the API. Leave empty for default.",
59
82
  advanced=True,
60
83
  ),
61
- MessageTextInput(
62
- name="ollama_base_url",
63
- display_name="Ollama API URL",
64
- info=f"Endpoint of the Ollama API (Ollama only). Defaults to {DEFAULT_OLLAMA_URL}",
65
- value=DEFAULT_OLLAMA_URL,
66
- show=False,
67
- real_time_refresh=True,
68
- load_from_db=True,
69
- ),
84
+ # Watson-specific inputs
70
85
  DropdownInput(
71
86
  name="base_url_ibm_watsonx",
72
87
  display_name="watsonx API Endpoint",
@@ -76,24 +91,6 @@ class EmbeddingModelComponent(LCEmbeddingsModel):
76
91
  show=False,
77
92
  real_time_refresh=True,
78
93
  ),
79
- DropdownInput(
80
- name="model",
81
- display_name="Model Name",
82
- options=OPENAI_EMBEDDING_MODEL_NAMES,
83
- value=OPENAI_EMBEDDING_MODEL_NAMES[0],
84
- info="Select the embedding model to use",
85
- real_time_refresh=True,
86
- refresh_button=True,
87
- ),
88
- SecretStrInput(
89
- name="api_key",
90
- display_name="OpenAI API Key",
91
- info="Model Provider API key",
92
- required=True,
93
- show=True,
94
- real_time_refresh=True,
95
- ),
96
- # Watson-specific inputs
97
94
  MessageTextInput(
98
95
  name="project_id",
99
96
  display_name="Project ID",
@@ -107,10 +104,28 @@ class EmbeddingModelComponent(LCEmbeddingsModel):
107
104
  "Only supported by certain models.",
108
105
  advanced=True,
109
106
  ),
110
- IntInput(name="chunk_size", display_name="Chunk Size", advanced=True, value=1000),
111
- FloatInput(name="request_timeout", display_name="Request Timeout", advanced=True),
112
- IntInput(name="max_retries", display_name="Max Retries", advanced=True, value=3),
113
- BoolInput(name="show_progress_bar", display_name="Show Progress Bar", advanced=True),
107
+ IntInput(
108
+ name="chunk_size",
109
+ display_name="Chunk Size",
110
+ advanced=True,
111
+ value=1000,
112
+ ),
113
+ FloatInput(
114
+ name="request_timeout",
115
+ display_name="Request Timeout",
116
+ advanced=True,
117
+ ),
118
+ IntInput(
119
+ name="max_retries",
120
+ display_name="Max Retries",
121
+ advanced=True,
122
+ value=3,
123
+ ),
124
+ BoolInput(
125
+ name="show_progress_bar",
126
+ display_name="Show Progress Bar",
127
+ advanced=True,
128
+ ),
114
129
  DictInput(
115
130
  name="model_kwargs",
116
131
  display_name="Model Kwargs",
@@ -133,221 +148,122 @@ class EmbeddingModelComponent(LCEmbeddingsModel):
133
148
  ),
134
149
  ]
135
150
 
136
- @staticmethod
137
- def fetch_ibm_models(base_url: str) -> list[str]:
138
- """Fetch available models from the watsonx.ai API."""
151
+ def build_embeddings(self) -> Embeddings:
152
+ """Build and return an embeddings instance based on the selected model."""
153
+ # If an Embeddings object is directly connected, return it
139
154
  try:
140
- endpoint = f"{base_url}/ml/v1/foundation_model_specs"
141
- params = {
142
- "version": "2024-09-16",
143
- "filters": "function_embedding,!lifecycle_withdrawn:and",
144
- }
145
- response = requests.get(endpoint, params=params, timeout=10)
146
- response.raise_for_status()
147
- data = response.json()
148
- models = [model["model_id"] for model in data.get("resources", [])]
149
- return sorted(models)
150
- except Exception: # noqa: BLE001
151
- logger.exception("Error fetching models")
152
- return WATSONX_EMBEDDING_MODEL_NAMES
155
+ from langchain_core.embeddings import Embeddings as BaseEmbeddings
153
156
 
154
- def build_embeddings(self) -> Embeddings:
155
- provider = self.provider
156
- model = self.model
157
- api_key = self.api_key
158
- api_base = self.api_base
159
- base_url_ibm_watsonx = self.base_url_ibm_watsonx
160
- ollama_base_url = self.ollama_base_url
161
- dimensions = self.dimensions
162
- chunk_size = self.chunk_size
163
- request_timeout = self.request_timeout
164
- max_retries = self.max_retries
165
- show_progress_bar = self.show_progress_bar
166
- model_kwargs = self.model_kwargs or {}
157
+ if isinstance(self.model, BaseEmbeddings):
158
+ return self.model
159
+ except ImportError:
160
+ pass
167
161
 
168
- if provider == "OpenAI":
169
- if not api_key:
170
- msg = "OpenAI API key is required when using OpenAI provider"
171
- raise ValueError(msg)
172
- return OpenAIEmbeddings(
173
- model=model,
174
- dimensions=dimensions or None,
175
- base_url=api_base or None,
176
- api_key=api_key,
177
- chunk_size=chunk_size,
178
- max_retries=max_retries,
179
- timeout=request_timeout or None,
180
- show_progress_bar=show_progress_bar,
181
- model_kwargs=model_kwargs,
182
- )
162
+ # Safely extract model configuration
163
+ if not self.model or not isinstance(self.model, list):
164
+ msg = "Model must be a non-empty list"
165
+ raise ValueError(msg)
183
166
 
184
- if provider == "Ollama":
185
- try:
186
- from langchain_ollama import OllamaEmbeddings
187
- except ImportError:
188
- try:
189
- from langchain_community.embeddings import OllamaEmbeddings
190
- except ImportError:
191
- msg = "Please install langchain-ollama: pip install langchain-ollama"
192
- raise ImportError(msg) from None
167
+ model = self.model[0]
168
+ model_name = model.get("name")
169
+ provider = model.get("provider")
170
+ metadata = model.get("metadata", {})
193
171
 
194
- transformed_base_url = transform_localhost_url(ollama_base_url)
172
+ # Get API key from user input or global variables
173
+ api_key = get_api_key_for_provider(self.user_id, provider, self.api_key)
195
174
 
196
- # Check if URL contains /v1 suffix (OpenAI-compatible mode)
197
- if transformed_base_url and transformed_base_url.rstrip("/").endswith("/v1"):
198
- # Strip /v1 suffix and log warning
199
- transformed_base_url = transformed_base_url.rstrip("/").removesuffix("/v1")
200
- logger.warning(
201
- "Detected '/v1' suffix in base URL. The Ollama component uses the native Ollama API, "
202
- "not the OpenAI-compatible API. The '/v1' suffix has been automatically removed. "
203
- "If you want to use the OpenAI-compatible API, please use the OpenAI component instead. "
204
- "Learn more at https://docs.ollama.com/openai#openai-compatibility"
205
- )
206
-
207
- return OllamaEmbeddings(
208
- model=model,
209
- base_url=transformed_base_url or "http://localhost:11434",
210
- **model_kwargs,
175
+ # Validate required fields (Ollama doesn't require API key)
176
+ if not api_key and provider != "Ollama":
177
+ msg = (
178
+ f"{provider} API key is required. "
179
+ f"Please provide it in the component or configure it globally as "
180
+ f"{provider.upper().replace(' ', '_')}_API_KEY."
211
181
  )
182
+ raise ValueError(msg)
212
183
 
213
- if provider == "IBM watsonx.ai":
214
- try:
215
- from langchain_ibm import WatsonxEmbeddings
216
- except ImportError:
217
- msg = "Please install langchain-ibm: pip install langchain-ibm"
218
- raise ImportError(msg) from None
184
+ if not model_name:
185
+ msg = "Model name is required"
186
+ raise ValueError(msg)
219
187
 
220
- if not api_key:
221
- msg = "IBM watsonx.ai API key is required when using IBM watsonx.ai provider"
222
- raise ValueError(msg)
188
+ # Get embedding class
189
+ embedding_class_name = metadata.get("embedding_class")
190
+ if not embedding_class_name:
191
+ msg = f"No embedding class defined in metadata for {model_name}"
192
+ raise ValueError(msg)
223
193
 
224
- project_id = self.project_id
194
+ embedding_class = get_embedding_classes().get(embedding_class_name)
195
+ if not embedding_class:
196
+ msg = f"Unknown embedding class: {embedding_class_name}"
197
+ raise ValueError(msg)
225
198
 
226
- if not project_id:
227
- msg = "Project ID is required for IBM watsonx.ai provider"
228
- raise ValueError(msg)
199
+ # Build kwargs using parameter mapping
200
+ kwargs = self._build_kwargs(model, metadata)
229
201
 
230
- from ibm_watsonx_ai import APIClient, Credentials
202
+ return embedding_class(**kwargs)
231
203
 
232
- credentials = Credentials(
233
- api_key=self.api_key,
234
- url=base_url_ibm_watsonx or "https://us-south.ml.cloud.ibm.com",
235
- )
204
+ def _build_kwargs(self, model: dict[str, Any], metadata: dict[str, Any]) -> dict[str, Any]:
205
+ """Build kwargs dictionary using parameter mapping."""
206
+ param_mapping = metadata.get("param_mapping", {})
207
+ if not param_mapping:
208
+ msg = "Parameter mapping not found in metadata"
209
+ raise ValueError(msg)
236
210
 
237
- api_client = APIClient(credentials)
211
+ kwargs = {}
238
212
 
239
- params = {
240
- EmbedTextParamsMetaNames.TRUNCATE_INPUT_TOKENS: self.truncate_input_tokens,
241
- EmbedTextParamsMetaNames.RETURN_OPTIONS: {"input_text": self.input_text},
242
- }
243
-
244
- return WatsonxEmbeddings(
245
- model_id=model,
246
- params=params,
247
- watsonx_client=api_client,
248
- project_id=project_id,
213
+ # Required parameters - handle both "model" and "model_id" (for watsonx)
214
+ if "model" in param_mapping:
215
+ kwargs[param_mapping["model"]] = model.get("name")
216
+ elif "model_id" in param_mapping:
217
+ kwargs[param_mapping["model_id"]] = model.get("name")
218
+ if "api_key" in param_mapping:
219
+ kwargs[param_mapping["api_key"]] = get_api_key_for_provider(
220
+ self.user_id,
221
+ model.get("provider"),
222
+ self.api_key,
249
223
  )
250
224
 
251
- msg = f"Unknown provider: {provider}"
252
- raise ValueError(msg)
253
-
254
- async def update_build_config(
255
- self, build_config: dotdict, field_value: Any, field_name: str | None = None
256
- ) -> dotdict:
257
- if field_name == "provider":
258
- if field_value == "OpenAI":
259
- build_config["model"]["options"] = OPENAI_EMBEDDING_MODEL_NAMES
260
- build_config["model"]["value"] = OPENAI_EMBEDDING_MODEL_NAMES[0]
261
- build_config["api_key"]["display_name"] = "OpenAI API Key"
262
- build_config["api_key"]["required"] = True
263
- build_config["api_key"]["show"] = True
264
- build_config["api_base"]["display_name"] = "OpenAI API Base URL"
265
- build_config["api_base"]["advanced"] = True
266
- build_config["api_base"]["show"] = True
267
- build_config["ollama_base_url"]["show"] = False
268
- build_config["project_id"]["show"] = False
269
- build_config["base_url_ibm_watsonx"]["show"] = False
270
- build_config["truncate_input_tokens"]["show"] = False
271
- build_config["input_text"]["show"] = False
272
- elif field_value == "Ollama":
273
- build_config["ollama_base_url"]["show"] = True
225
+ # Optional parameters with their values
226
+ provider = model.get("provider")
227
+ optional_params = {
228
+ "api_base": self.api_base if self.api_base else None,
229
+ "dimensions": int(self.dimensions) if self.dimensions else None,
230
+ "chunk_size": int(self.chunk_size) if self.chunk_size else None,
231
+ "request_timeout": float(self.request_timeout) if self.request_timeout else None,
232
+ "max_retries": int(self.max_retries) if self.max_retries else None,
233
+ "show_progress_bar": self.show_progress_bar if hasattr(self, "show_progress_bar") else None,
234
+ "model_kwargs": self.model_kwargs if self.model_kwargs else None,
235
+ }
274
236
 
275
- if await is_valid_ollama_url(url=self.ollama_base_url):
276
- try:
277
- models = await get_ollama_models(
278
- base_url_value=self.ollama_base_url,
279
- desired_capability=DESIRED_CAPABILITY,
280
- json_models_key=JSON_MODELS_KEY,
281
- json_name_key=JSON_NAME_KEY,
282
- json_capabilities_key=JSON_CAPABILITIES_KEY,
283
- )
284
- build_config["model"]["options"] = models
285
- build_config["model"]["value"] = models[0] if models else ""
286
- except ValueError:
287
- build_config["model"]["options"] = []
288
- build_config["model"]["value"] = ""
289
- else:
290
- build_config["model"]["options"] = []
291
- build_config["model"]["value"] = ""
292
- build_config["truncate_input_tokens"]["show"] = False
293
- build_config["input_text"]["show"] = False
294
- build_config["api_key"]["display_name"] = "API Key (Optional)"
295
- build_config["api_key"]["required"] = False
296
- build_config["api_key"]["show"] = False
297
- build_config["api_base"]["show"] = False
298
- build_config["project_id"]["show"] = False
299
- build_config["base_url_ibm_watsonx"]["show"] = False
237
+ # Watson-specific parameters
238
+ if provider in {"IBM WatsonX", "IBM watsonx.ai"}:
239
+ # Map base_url_ibm_watsonx to "url" parameter for watsonx
240
+ if "url" in param_mapping:
241
+ url_value = (
242
+ self.base_url_ibm_watsonx
243
+ if hasattr(self, "base_url_ibm_watsonx") and self.base_url_ibm_watsonx
244
+ else "https://us-south.ml.cloud.ibm.com"
245
+ )
246
+ kwargs[param_mapping["url"]] = url_value
247
+ # Map project_id for watsonx
248
+ if hasattr(self, "project_id") and self.project_id and "project_id" in param_mapping:
249
+ kwargs[param_mapping["project_id"]] = self.project_id
300
250
 
301
- elif field_value == "IBM watsonx.ai":
302
- build_config["model"]["options"] = self.fetch_ibm_models(base_url=self.base_url_ibm_watsonx)
303
- build_config["model"]["value"] = self.fetch_ibm_models(base_url=self.base_url_ibm_watsonx)[0]
304
- build_config["api_key"]["display_name"] = "IBM watsonx.ai API Key"
305
- build_config["api_key"]["required"] = True
306
- build_config["api_key"]["show"] = True
307
- build_config["api_base"]["show"] = False
308
- build_config["ollama_base_url"]["show"] = False
309
- build_config["base_url_ibm_watsonx"]["show"] = True
310
- build_config["project_id"]["show"] = True
311
- build_config["truncate_input_tokens"]["show"] = True
312
- build_config["input_text"]["show"] = True
313
- elif field_name == "base_url_ibm_watsonx":
314
- build_config["model"]["options"] = self.fetch_ibm_models(base_url=field_value)
315
- build_config["model"]["value"] = self.fetch_ibm_models(base_url=field_value)[0]
316
- elif field_name == "ollama_base_url":
317
- # # Refresh Ollama models when base URL changes
318
- # if hasattr(self, "provider") and self.provider == "Ollama":
319
- # Use field_value if provided, otherwise fall back to instance attribute
320
- ollama_url = self.ollama_base_url
321
- if await is_valid_ollama_url(url=ollama_url):
322
- try:
323
- models = await get_ollama_models(
324
- base_url_value=ollama_url,
325
- desired_capability=DESIRED_CAPABILITY,
326
- json_models_key=JSON_MODELS_KEY,
327
- json_name_key=JSON_NAME_KEY,
328
- json_capabilities_key=JSON_CAPABILITIES_KEY,
329
- )
330
- build_config["model"]["options"] = models
331
- build_config["model"]["value"] = models[0] if models else ""
332
- except ValueError:
333
- await logger.awarning("Failed to fetch Ollama embedding models.")
334
- build_config["model"]["options"] = []
335
- build_config["model"]["value"] = ""
251
+ # Ollama-specific parameters
252
+ if provider == "Ollama" and "base_url" in param_mapping:
253
+ # Map api_base to "base_url" parameter for Ollama
254
+ base_url_value = self.api_base if hasattr(self, "api_base") and self.api_base else "http://localhost:11434"
255
+ kwargs[param_mapping["base_url"]] = base_url_value
336
256
 
337
- elif field_name == "model" and self.provider == "Ollama":
338
- ollama_url = self.ollama_base_url
339
- if await is_valid_ollama_url(url=ollama_url):
340
- try:
341
- models = await get_ollama_models(
342
- base_url_value=ollama_url,
343
- desired_capability=DESIRED_CAPABILITY,
344
- json_models_key=JSON_MODELS_KEY,
345
- json_name_key=JSON_NAME_KEY,
346
- json_capabilities_key=JSON_CAPABILITIES_KEY,
347
- )
348
- build_config["model"]["options"] = models
349
- except ValueError:
350
- await logger.awarning("Failed to refresh Ollama embedding models.")
351
- build_config["model"]["options"] = []
257
+ # Add optional parameters if they have values and are mapped
258
+ for param_name, param_value in optional_params.items():
259
+ if param_value is not None and param_name in param_mapping:
260
+ # Special handling for request_timeout with Google provider
261
+ if param_name == "request_timeout":
262
+ if provider == "Google" and isinstance(param_value, (int, float)):
263
+ kwargs[param_mapping[param_name]] = {"timeout": param_value}
264
+ else:
265
+ kwargs[param_mapping[param_name]] = param_value
266
+ else:
267
+ kwargs[param_mapping[param_name]] = param_value
352
268
 
353
- return build_config
269
+ return kwargs