lfx-nightly 0.2.0.dev0__py3-none-any.whl → 0.2.0.dev41__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.
- lfx/_assets/component_index.json +1 -1
- lfx/base/agents/agent.py +21 -4
- lfx/base/agents/altk_base_agent.py +393 -0
- lfx/base/agents/altk_tool_wrappers.py +565 -0
- lfx/base/agents/events.py +2 -1
- lfx/base/composio/composio_base.py +159 -224
- lfx/base/data/base_file.py +97 -20
- lfx/base/data/docling_utils.py +61 -10
- lfx/base/data/storage_utils.py +301 -0
- lfx/base/data/utils.py +178 -14
- lfx/base/mcp/util.py +2 -2
- lfx/base/models/anthropic_constants.py +21 -12
- lfx/base/models/groq_constants.py +74 -58
- lfx/base/models/groq_model_discovery.py +265 -0
- lfx/base/models/model.py +1 -1
- lfx/base/models/model_utils.py +100 -0
- lfx/base/models/openai_constants.py +7 -0
- lfx/base/models/watsonx_constants.py +32 -8
- lfx/base/tools/run_flow.py +601 -129
- lfx/cli/commands.py +9 -4
- lfx/cli/common.py +2 -2
- lfx/cli/run.py +1 -1
- lfx/cli/script_loader.py +53 -11
- lfx/components/Notion/create_page.py +1 -1
- lfx/components/Notion/list_database_properties.py +1 -1
- lfx/components/Notion/list_pages.py +1 -1
- lfx/components/Notion/list_users.py +1 -1
- lfx/components/Notion/page_content_viewer.py +1 -1
- lfx/components/Notion/search.py +1 -1
- lfx/components/Notion/update_page_property.py +1 -1
- lfx/components/__init__.py +19 -5
- lfx/components/{agents → altk}/__init__.py +5 -9
- lfx/components/altk/altk_agent.py +193 -0
- lfx/components/apify/apify_actor.py +1 -1
- lfx/components/composio/__init__.py +70 -18
- lfx/components/composio/apollo_composio.py +11 -0
- lfx/components/composio/bitbucket_composio.py +11 -0
- lfx/components/composio/canva_composio.py +11 -0
- lfx/components/composio/coda_composio.py +11 -0
- lfx/components/composio/composio_api.py +10 -0
- lfx/components/composio/discord_composio.py +1 -1
- lfx/components/composio/elevenlabs_composio.py +11 -0
- lfx/components/composio/exa_composio.py +11 -0
- lfx/components/composio/firecrawl_composio.py +11 -0
- lfx/components/composio/fireflies_composio.py +11 -0
- lfx/components/composio/gmail_composio.py +1 -1
- lfx/components/composio/googlebigquery_composio.py +11 -0
- lfx/components/composio/googlecalendar_composio.py +1 -1
- lfx/components/composio/googledocs_composio.py +1 -1
- lfx/components/composio/googlemeet_composio.py +1 -1
- lfx/components/composio/googlesheets_composio.py +1 -1
- lfx/components/composio/googletasks_composio.py +1 -1
- lfx/components/composio/heygen_composio.py +11 -0
- lfx/components/composio/mem0_composio.py +11 -0
- lfx/components/composio/peopledatalabs_composio.py +11 -0
- lfx/components/composio/perplexityai_composio.py +11 -0
- lfx/components/composio/serpapi_composio.py +11 -0
- lfx/components/composio/slack_composio.py +3 -574
- lfx/components/composio/slackbot_composio.py +1 -1
- lfx/components/composio/snowflake_composio.py +11 -0
- lfx/components/composio/tavily_composio.py +11 -0
- lfx/components/composio/youtube_composio.py +2 -2
- lfx/components/cuga/__init__.py +34 -0
- lfx/components/cuga/cuga_agent.py +730 -0
- lfx/components/data/__init__.py +78 -28
- lfx/components/data_source/__init__.py +58 -0
- lfx/components/{data → data_source}/api_request.py +26 -3
- lfx/components/{data → data_source}/csv_to_data.py +15 -10
- lfx/components/{data → data_source}/json_to_data.py +15 -8
- lfx/components/{data → data_source}/news_search.py +1 -1
- lfx/components/{data → data_source}/rss.py +1 -1
- lfx/components/{data → data_source}/sql_executor.py +1 -1
- lfx/components/{data → data_source}/url.py +1 -1
- lfx/components/{data → data_source}/web_search.py +1 -1
- lfx/components/datastax/astradb_cql.py +1 -1
- lfx/components/datastax/astradb_graph.py +1 -1
- lfx/components/datastax/astradb_tool.py +1 -1
- lfx/components/datastax/astradb_vectorstore.py +1 -1
- lfx/components/datastax/hcd.py +1 -1
- lfx/components/deactivated/json_document_builder.py +1 -1
- lfx/components/docling/__init__.py +0 -3
- lfx/components/docling/chunk_docling_document.py +3 -1
- lfx/components/docling/export_docling_document.py +3 -1
- lfx/components/elastic/elasticsearch.py +1 -1
- lfx/components/files_and_knowledge/__init__.py +47 -0
- lfx/components/{data → files_and_knowledge}/directory.py +1 -1
- lfx/components/{data → files_and_knowledge}/file.py +304 -24
- lfx/components/{knowledge_bases → files_and_knowledge}/retrieval.py +2 -2
- lfx/components/{data → files_and_knowledge}/save_file.py +218 -31
- lfx/components/flow_controls/__init__.py +58 -0
- lfx/components/{logic → flow_controls}/conditional_router.py +1 -1
- lfx/components/{logic → flow_controls}/loop.py +43 -9
- lfx/components/flow_controls/run_flow.py +108 -0
- lfx/components/glean/glean_search_api.py +1 -1
- lfx/components/groq/groq.py +35 -28
- lfx/components/helpers/__init__.py +102 -0
- lfx/components/ibm/watsonx.py +7 -1
- lfx/components/input_output/__init__.py +3 -1
- lfx/components/input_output/chat.py +4 -3
- lfx/components/input_output/chat_output.py +10 -4
- lfx/components/input_output/text.py +1 -1
- lfx/components/input_output/text_output.py +1 -1
- lfx/components/{data → input_output}/webhook.py +1 -1
- lfx/components/knowledge_bases/__init__.py +59 -4
- lfx/components/langchain_utilities/character.py +1 -1
- lfx/components/langchain_utilities/csv_agent.py +84 -16
- lfx/components/langchain_utilities/json_agent.py +67 -12
- lfx/components/langchain_utilities/language_recursive.py +1 -1
- lfx/components/llm_operations/__init__.py +46 -0
- lfx/components/{processing → llm_operations}/batch_run.py +17 -8
- lfx/components/{processing → llm_operations}/lambda_filter.py +1 -1
- lfx/components/{logic → llm_operations}/llm_conditional_router.py +1 -1
- lfx/components/{processing/llm_router.py → llm_operations/llm_selector.py} +3 -3
- lfx/components/{processing → llm_operations}/structured_output.py +1 -1
- lfx/components/logic/__init__.py +126 -0
- lfx/components/mem0/mem0_chat_memory.py +11 -0
- lfx/components/models/__init__.py +64 -9
- lfx/components/models_and_agents/__init__.py +49 -0
- lfx/components/{agents → models_and_agents}/agent.py +6 -4
- lfx/components/models_and_agents/embedding_model.py +353 -0
- lfx/components/models_and_agents/language_model.py +398 -0
- lfx/components/{agents → models_and_agents}/mcp_component.py +53 -44
- lfx/components/{helpers → models_and_agents}/memory.py +1 -1
- lfx/components/nvidia/system_assist.py +1 -1
- lfx/components/olivya/olivya.py +1 -1
- lfx/components/ollama/ollama.py +24 -5
- lfx/components/processing/__init__.py +9 -60
- lfx/components/processing/converter.py +1 -1
- lfx/components/processing/dataframe_operations.py +1 -1
- lfx/components/processing/parse_json_data.py +2 -2
- lfx/components/processing/parser.py +1 -1
- lfx/components/processing/split_text.py +1 -1
- lfx/components/qdrant/qdrant.py +1 -1
- lfx/components/redis/redis.py +1 -1
- lfx/components/twelvelabs/split_video.py +10 -0
- lfx/components/twelvelabs/video_file.py +12 -0
- lfx/components/utilities/__init__.py +43 -0
- lfx/components/{helpers → utilities}/calculator_core.py +1 -1
- lfx/components/{helpers → utilities}/current_date.py +1 -1
- lfx/components/{processing → utilities}/python_repl_core.py +1 -1
- lfx/components/vectorstores/local_db.py +9 -0
- lfx/components/youtube/youtube_transcripts.py +118 -30
- lfx/custom/custom_component/component.py +57 -1
- lfx/custom/custom_component/custom_component.py +68 -6
- lfx/custom/directory_reader/directory_reader.py +5 -2
- lfx/graph/edge/base.py +43 -20
- lfx/graph/state/model.py +15 -2
- lfx/graph/utils.py +6 -0
- lfx/graph/vertex/param_handler.py +10 -7
- lfx/helpers/__init__.py +12 -0
- lfx/helpers/flow.py +117 -0
- lfx/inputs/input_mixin.py +24 -1
- lfx/inputs/inputs.py +13 -1
- lfx/interface/components.py +161 -83
- lfx/log/logger.py +5 -3
- lfx/schema/image.py +2 -12
- lfx/services/database/__init__.py +5 -0
- lfx/services/database/service.py +25 -0
- lfx/services/deps.py +87 -22
- lfx/services/interfaces.py +5 -0
- lfx/services/manager.py +24 -10
- lfx/services/mcp_composer/service.py +1029 -162
- lfx/services/session.py +5 -0
- lfx/services/settings/auth.py +18 -11
- lfx/services/settings/base.py +56 -30
- lfx/services/settings/constants.py +8 -0
- lfx/services/storage/local.py +108 -46
- lfx/services/storage/service.py +171 -29
- lfx/template/field/base.py +3 -0
- lfx/utils/image.py +29 -11
- lfx/utils/ssrf_protection.py +384 -0
- lfx/utils/validate_cloud.py +26 -0
- {lfx_nightly-0.2.0.dev0.dist-info → lfx_nightly-0.2.0.dev41.dist-info}/METADATA +38 -22
- {lfx_nightly-0.2.0.dev0.dist-info → lfx_nightly-0.2.0.dev41.dist-info}/RECORD +189 -160
- {lfx_nightly-0.2.0.dev0.dist-info → lfx_nightly-0.2.0.dev41.dist-info}/WHEEL +1 -1
- lfx/components/agents/altk_agent.py +0 -366
- lfx/components/agents/cuga_agent.py +0 -1013
- lfx/components/docling/docling_remote_vlm.py +0 -284
- lfx/components/logic/run_flow.py +0 -71
- lfx/components/models/embedding_model.py +0 -195
- lfx/components/models/language_model.py +0 -144
- lfx/components/processing/dataframe_to_toolset.py +0 -259
- /lfx/components/{data → data_source}/mock_data.py +0 -0
- /lfx/components/{knowledge_bases → files_and_knowledge}/ingestion.py +0 -0
- /lfx/components/{logic → flow_controls}/data_conditional_router.py +0 -0
- /lfx/components/{logic → flow_controls}/flow_tool.py +0 -0
- /lfx/components/{logic → flow_controls}/listen.py +0 -0
- /lfx/components/{logic → flow_controls}/notify.py +0 -0
- /lfx/components/{logic → flow_controls}/pass_message.py +0 -0
- /lfx/components/{logic → flow_controls}/sub_flow.py +0 -0
- /lfx/components/{processing → models_and_agents}/prompt.py +0 -0
- /lfx/components/{helpers → processing}/create_list.py +0 -0
- /lfx/components/{helpers → processing}/output_parser.py +0 -0
- /lfx/components/{helpers → processing}/store_message.py +0 -0
- /lfx/components/{helpers → utilities}/id_generator.py +0 -0
- {lfx_nightly-0.2.0.dev0.dist-info → lfx_nightly-0.2.0.dev41.dist-info}/entry_points.txt +0 -0
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from typing import TYPE_CHECKING, Any
|
|
4
|
+
|
|
5
|
+
from lfx.components._importing import import_mod
|
|
6
|
+
|
|
7
|
+
if TYPE_CHECKING:
|
|
8
|
+
from lfx.components.models_and_agents.agent import AgentComponent
|
|
9
|
+
from lfx.components.models_and_agents.embedding_model import EmbeddingModelComponent
|
|
10
|
+
from lfx.components.models_and_agents.language_model import LanguageModelComponent
|
|
11
|
+
from lfx.components.models_and_agents.mcp_component import MCPToolsComponent
|
|
12
|
+
from lfx.components.models_and_agents.memory import MemoryComponent
|
|
13
|
+
from lfx.components.models_and_agents.prompt import PromptComponent
|
|
14
|
+
|
|
15
|
+
_dynamic_imports = {
|
|
16
|
+
"AgentComponent": "agent",
|
|
17
|
+
"EmbeddingModelComponent": "embedding_model",
|
|
18
|
+
"LanguageModelComponent": "language_model",
|
|
19
|
+
"MCPToolsComponent": "mcp_component",
|
|
20
|
+
"MemoryComponent": "memory",
|
|
21
|
+
"PromptComponent": "prompt",
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
__all__ = [
|
|
25
|
+
"AgentComponent",
|
|
26
|
+
"EmbeddingModelComponent",
|
|
27
|
+
"LanguageModelComponent",
|
|
28
|
+
"MCPToolsComponent",
|
|
29
|
+
"MemoryComponent",
|
|
30
|
+
"PromptComponent",
|
|
31
|
+
]
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
def __getattr__(attr_name: str) -> Any:
|
|
35
|
+
"""Lazily import model and agent components on attribute access."""
|
|
36
|
+
if attr_name not in _dynamic_imports:
|
|
37
|
+
msg = f"module '{__name__}' has no attribute '{attr_name}'"
|
|
38
|
+
raise AttributeError(msg)
|
|
39
|
+
try:
|
|
40
|
+
result = import_mod(attr_name, _dynamic_imports[attr_name], __spec__.parent)
|
|
41
|
+
except (ModuleNotFoundError, ImportError, AttributeError) as e:
|
|
42
|
+
msg = f"Could not import '{attr_name}' from '{__name__}': {e}"
|
|
43
|
+
raise AttributeError(msg) from e
|
|
44
|
+
globals()[attr_name] = result
|
|
45
|
+
return result
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
def __dir__() -> list[str]:
|
|
49
|
+
return list(__all__)
|
|
@@ -14,9 +14,9 @@ from lfx.base.models.model_input_constants import (
|
|
|
14
14
|
MODELS_METADATA,
|
|
15
15
|
)
|
|
16
16
|
from lfx.base.models.model_utils import get_model_name
|
|
17
|
-
from lfx.components.helpers
|
|
18
|
-
from lfx.components.helpers.memory import MemoryComponent
|
|
17
|
+
from lfx.components.helpers import CurrentDateComponent
|
|
19
18
|
from lfx.components.langchain_utilities.tool_calling import ToolCallingAgentComponent
|
|
19
|
+
from lfx.components.models_and_agents.memory import MemoryComponent
|
|
20
20
|
from lfx.custom.custom_component.component import get_component_toolkit
|
|
21
21
|
from lfx.custom.utils import update_component_build_config
|
|
22
22
|
from lfx.helpers.base_model import build_model_from_schema
|
|
@@ -619,9 +619,11 @@ class AgentComponent(ToolCallingAgentComponent):
|
|
|
619
619
|
# Call each component class's update_build_config method
|
|
620
620
|
# remove the prefix from the field_name
|
|
621
621
|
if isinstance(field_name, str) and isinstance(prefix, str):
|
|
622
|
-
|
|
622
|
+
field_name_without_prefix = field_name.replace(prefix, "")
|
|
623
|
+
else:
|
|
624
|
+
field_name_without_prefix = field_name
|
|
623
625
|
build_config = await update_component_build_config(
|
|
624
|
-
component_class, build_config, field_value,
|
|
626
|
+
component_class, build_config, field_value, field_name_without_prefix
|
|
625
627
|
)
|
|
626
628
|
return dotdict({k: v.to_dict() if hasattr(v, "to_dict") else v for k, v in build_config.items()})
|
|
627
629
|
|
|
@@ -0,0 +1,353 @@
|
|
|
1
|
+
from typing import Any
|
|
2
|
+
|
|
3
|
+
import requests
|
|
4
|
+
from ibm_watsonx_ai.metanames import EmbedTextParamsMetaNames
|
|
5
|
+
from langchain_openai import OpenAIEmbeddings
|
|
6
|
+
|
|
7
|
+
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,
|
|
13
|
+
)
|
|
14
|
+
from lfx.field_typing import Embeddings
|
|
15
|
+
from lfx.io import (
|
|
16
|
+
BoolInput,
|
|
17
|
+
DictInput,
|
|
18
|
+
DropdownInput,
|
|
19
|
+
FloatInput,
|
|
20
|
+
IntInput,
|
|
21
|
+
MessageTextInput,
|
|
22
|
+
SecretStrInput,
|
|
23
|
+
)
|
|
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
|
+
|
|
36
|
+
|
|
37
|
+
class EmbeddingModelComponent(LCEmbeddingsModel):
|
|
38
|
+
display_name = "Embedding Model"
|
|
39
|
+
description = "Generate embeddings using a specified provider."
|
|
40
|
+
documentation: str = "https://docs.langflow.org/components-embedding-models"
|
|
41
|
+
icon = "binary"
|
|
42
|
+
name = "EmbeddingModel"
|
|
43
|
+
category = "models"
|
|
44
|
+
|
|
45
|
+
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",
|
|
52
|
+
real_time_refresh=True,
|
|
53
|
+
options_metadata=[{"icon": "OpenAI"}, {"icon": "Ollama"}, {"icon": "WatsonxAI"}],
|
|
54
|
+
),
|
|
55
|
+
MessageTextInput(
|
|
56
|
+
name="api_base",
|
|
57
|
+
display_name="API Base URL",
|
|
58
|
+
info="Base URL for the API. Leave empty for default.",
|
|
59
|
+
advanced=True,
|
|
60
|
+
),
|
|
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
|
+
),
|
|
70
|
+
DropdownInput(
|
|
71
|
+
name="base_url_ibm_watsonx",
|
|
72
|
+
display_name="watsonx API Endpoint",
|
|
73
|
+
info="The base URL of the API (IBM watsonx.ai only)",
|
|
74
|
+
options=IBM_WATSONX_URLS,
|
|
75
|
+
value=IBM_WATSONX_URLS[0],
|
|
76
|
+
show=False,
|
|
77
|
+
real_time_refresh=True,
|
|
78
|
+
),
|
|
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
|
+
MessageTextInput(
|
|
98
|
+
name="project_id",
|
|
99
|
+
display_name="Project ID",
|
|
100
|
+
info="IBM watsonx.ai Project ID (required for IBM watsonx.ai)",
|
|
101
|
+
show=False,
|
|
102
|
+
),
|
|
103
|
+
IntInput(
|
|
104
|
+
name="dimensions",
|
|
105
|
+
display_name="Dimensions",
|
|
106
|
+
info="The number of dimensions the resulting output embeddings should have. "
|
|
107
|
+
"Only supported by certain models.",
|
|
108
|
+
advanced=True,
|
|
109
|
+
),
|
|
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),
|
|
114
|
+
DictInput(
|
|
115
|
+
name="model_kwargs",
|
|
116
|
+
display_name="Model Kwargs",
|
|
117
|
+
advanced=True,
|
|
118
|
+
info="Additional keyword arguments to pass to the model.",
|
|
119
|
+
),
|
|
120
|
+
IntInput(
|
|
121
|
+
name="truncate_input_tokens",
|
|
122
|
+
display_name="Truncate Input Tokens",
|
|
123
|
+
advanced=True,
|
|
124
|
+
value=200,
|
|
125
|
+
show=False,
|
|
126
|
+
),
|
|
127
|
+
BoolInput(
|
|
128
|
+
name="input_text",
|
|
129
|
+
display_name="Include the original text in the output",
|
|
130
|
+
value=True,
|
|
131
|
+
advanced=True,
|
|
132
|
+
show=False,
|
|
133
|
+
),
|
|
134
|
+
]
|
|
135
|
+
|
|
136
|
+
@staticmethod
|
|
137
|
+
def fetch_ibm_models(base_url: str) -> list[str]:
|
|
138
|
+
"""Fetch available models from the watsonx.ai API."""
|
|
139
|
+
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
|
|
153
|
+
|
|
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 {}
|
|
167
|
+
|
|
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
|
+
)
|
|
183
|
+
|
|
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
|
|
193
|
+
|
|
194
|
+
transformed_base_url = transform_localhost_url(ollama_base_url)
|
|
195
|
+
|
|
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,
|
|
211
|
+
)
|
|
212
|
+
|
|
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
|
|
219
|
+
|
|
220
|
+
if not api_key:
|
|
221
|
+
msg = "IBM watsonx.ai API key is required when using IBM watsonx.ai provider"
|
|
222
|
+
raise ValueError(msg)
|
|
223
|
+
|
|
224
|
+
project_id = self.project_id
|
|
225
|
+
|
|
226
|
+
if not project_id:
|
|
227
|
+
msg = "Project ID is required for IBM watsonx.ai provider"
|
|
228
|
+
raise ValueError(msg)
|
|
229
|
+
|
|
230
|
+
from ibm_watsonx_ai import APIClient, Credentials
|
|
231
|
+
|
|
232
|
+
credentials = Credentials(
|
|
233
|
+
api_key=self.api_key,
|
|
234
|
+
url=base_url_ibm_watsonx or "https://us-south.ml.cloud.ibm.com",
|
|
235
|
+
)
|
|
236
|
+
|
|
237
|
+
api_client = APIClient(credentials)
|
|
238
|
+
|
|
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,
|
|
249
|
+
)
|
|
250
|
+
|
|
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
|
|
274
|
+
|
|
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
|
|
300
|
+
|
|
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"] = ""
|
|
336
|
+
|
|
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"] = []
|
|
352
|
+
|
|
353
|
+
return build_config
|