mirror of
https://github.com/langflow-ai/langflow.git
synced 2026-07-27 18:39:00 +08:00
feat: Add IBM watsonx.ai and Ollama to LanguageModelComponent (#10471)
* Add IBM watsonx.ai support to LanguageModelComponent Extended LanguageModelComponent to support IBM watsonx.ai as a provider, including dynamic model fetching, new input fields for API endpoint and project ID, and integration with ChatWatsonx. Updated starter project JSONs to reflect these changes and enable selection of IBM watsonx.ai models. * Add Ollama support to LanguageModelComponent Extended the LanguageModelComponent to support Ollama as a provider, including dynamic model fetching from the Ollama API and related UI input fields. Updated build_model and update_build_config logic to handle Ollama-specific configuration and improved provider switching logic for all supported providers. * [autofix.ci] apply automated fixes * [autofix.ci] apply automated fixes (attempt 2/3) * flow updates * Update component_index.json * Add context_id support and expand model providers Introduces a context_id input to ChatInput and ChatOutput components for enhanced chat memory management. Expands LanguageModelComponent to support IBM watsonx.ai and Ollama providers, including dynamic model fetching and related configuration options. * [autofix.ci] apply automated fixes * [autofix.ci] apply automated fixes (attempt 2/3) * [autofix.ci] apply automated fixes (attempt 3/3) * Add IBM watsonx and Ollama support to LanguageModelComponent Refactored LanguageModelComponent to support IBM watsonx and Ollama providers, including new input fields and validation logic. Updated build config logic and tests to handle provider-specific options, error cases, and model instantiation for IBM watsonx and Ollama. * update to the componentn index and templates * fix ruff * Update component_index.json * template updates --------- Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
This commit is contained in:
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@ -1,13 +1,15 @@
|
||||
import os
|
||||
from unittest.mock import patch
|
||||
|
||||
import pytest
|
||||
from langchain_anthropic import ChatAnthropic
|
||||
from langchain_google_genai import ChatGoogleGenerativeAI
|
||||
from langchain_ollama import ChatOllama
|
||||
from langchain_openai import ChatOpenAI
|
||||
from lfx.base.models.anthropic_constants import ANTHROPIC_MODELS
|
||||
from lfx.base.models.google_generative_ai_constants import GOOGLE_GENERATIVE_AI_MODELS
|
||||
from lfx.base.models.openai_constants import OPENAI_CHAT_MODEL_NAMES, OPENAI_REASONING_MODEL_NAMES
|
||||
from lfx.components.models.language_model import LanguageModelComponent
|
||||
from lfx.components.models.language_model import IBM_WATSONX_DEFAULT_MODELS, LanguageModelComponent
|
||||
|
||||
from tests.base import ComponentTestBaseWithoutClient
|
||||
|
||||
@ -63,34 +65,94 @@ class TestLanguageModelComponent(ComponentTestBaseWithoutClient):
|
||||
component = component_class(**default_kwargs)
|
||||
build_config = {
|
||||
"model_name": {"options": [], "value": ""},
|
||||
"api_key": {"display_name": "API Key"},
|
||||
"api_key": {"display_name": "API Key", "show": False},
|
||||
"base_url_ibm_watsonx": {"show": False},
|
||||
"project_id": {"show": False},
|
||||
"ollama_base_url": {"show": False},
|
||||
}
|
||||
updated_config = component.update_build_config(build_config, "OpenAI", "provider")
|
||||
assert updated_config["model_name"]["options"] == OPENAI_CHAT_MODEL_NAMES + OPENAI_REASONING_MODEL_NAMES
|
||||
assert updated_config["model_name"]["value"] == OPENAI_CHAT_MODEL_NAMES[0]
|
||||
assert updated_config["api_key"]["display_name"] == "OpenAI API Key"
|
||||
assert updated_config["api_key"]["show"] is True
|
||||
assert updated_config["base_url_ibm_watsonx"]["show"] is False
|
||||
assert updated_config["project_id"]["show"] is False
|
||||
assert updated_config["ollama_base_url"]["show"] is False
|
||||
|
||||
async def test_update_build_config_anthropic(self, component_class, default_kwargs):
|
||||
component = component_class(**default_kwargs)
|
||||
build_config = {
|
||||
"model_name": {"options": [], "value": ""},
|
||||
"api_key": {"display_name": "API Key"},
|
||||
"api_key": {"display_name": "API Key", "show": False},
|
||||
"base_url_ibm_watsonx": {"show": False},
|
||||
"project_id": {"show": False},
|
||||
"ollama_base_url": {"show": False},
|
||||
}
|
||||
updated_config = component.update_build_config(build_config, "Anthropic", "provider")
|
||||
assert updated_config["model_name"]["options"] == ANTHROPIC_MODELS
|
||||
assert updated_config["model_name"]["value"] == ANTHROPIC_MODELS[0]
|
||||
assert updated_config["api_key"]["display_name"] == "Anthropic API Key"
|
||||
assert updated_config["api_key"]["show"] is True
|
||||
assert updated_config["base_url_ibm_watsonx"]["show"] is False
|
||||
assert updated_config["project_id"]["show"] is False
|
||||
assert updated_config["ollama_base_url"]["show"] is False
|
||||
|
||||
async def test_update_build_config_google(self, component_class, default_kwargs):
|
||||
component = component_class(**default_kwargs)
|
||||
build_config = {
|
||||
"model_name": {"options": [], "value": ""},
|
||||
"api_key": {"display_name": "API Key"},
|
||||
"api_key": {"display_name": "API Key", "show": False},
|
||||
"base_url_ibm_watsonx": {"show": False},
|
||||
"project_id": {"show": False},
|
||||
"ollama_base_url": {"show": False},
|
||||
}
|
||||
updated_config = component.update_build_config(build_config, "Google", "provider")
|
||||
assert updated_config["model_name"]["options"] == GOOGLE_GENERATIVE_AI_MODELS
|
||||
assert updated_config["model_name"]["value"] == GOOGLE_GENERATIVE_AI_MODELS[0]
|
||||
assert updated_config["api_key"]["display_name"] == "Google API Key"
|
||||
assert updated_config["api_key"]["show"] is True
|
||||
assert updated_config["base_url_ibm_watsonx"]["show"] is False
|
||||
assert updated_config["project_id"]["show"] is False
|
||||
assert updated_config["ollama_base_url"]["show"] is False
|
||||
|
||||
async def test_update_build_config_ibm_watsonx(self, component_class, default_kwargs):
|
||||
component = component_class(**default_kwargs)
|
||||
build_config = {
|
||||
"model_name": {"options": [], "value": ""},
|
||||
"api_key": {"display_name": "API Key", "show": False},
|
||||
"base_url_ibm_watsonx": {"show": False},
|
||||
"project_id": {"show": False},
|
||||
"ollama_base_url": {"show": False},
|
||||
}
|
||||
updated_config = component.update_build_config(build_config, "IBM watsonx.ai", "provider")
|
||||
assert updated_config["model_name"]["options"] == IBM_WATSONX_DEFAULT_MODELS
|
||||
assert updated_config["model_name"]["value"] == IBM_WATSONX_DEFAULT_MODELS[0]
|
||||
assert updated_config["api_key"]["display_name"] == "IBM API Key"
|
||||
assert updated_config["api_key"]["show"] is True
|
||||
assert updated_config["base_url_ibm_watsonx"]["show"] is True
|
||||
assert updated_config["project_id"]["show"] is True
|
||||
assert updated_config["ollama_base_url"]["show"] is False
|
||||
|
||||
@patch.object(LanguageModelComponent, "fetch_ollama_models")
|
||||
async def test_update_build_config_ollama(self, mock_fetch_ollama, component_class, default_kwargs):
|
||||
# Mock the fetch_ollama_models method to return test models
|
||||
mock_fetch_ollama.return_value = ["llama2", "mistral", "codellama"]
|
||||
|
||||
component = component_class(**default_kwargs)
|
||||
build_config = {
|
||||
"model_name": {"options": [], "value": ""},
|
||||
"api_key": {"display_name": "API Key", "show": True},
|
||||
"base_url_ibm_watsonx": {"show": False},
|
||||
"project_id": {"show": False},
|
||||
"ollama_base_url": {"show": False, "value": "http://localhost:11434"},
|
||||
}
|
||||
updated_config = component.update_build_config(build_config, "Ollama", "provider")
|
||||
assert updated_config["model_name"]["options"] == ["llama2", "mistral", "codellama"]
|
||||
assert updated_config["model_name"]["value"] == "llama2"
|
||||
assert updated_config["api_key"]["show"] is False
|
||||
assert updated_config["base_url_ibm_watsonx"]["show"] is False
|
||||
assert updated_config["project_id"]["show"] is False
|
||||
assert updated_config["ollama_base_url"]["show"] is True
|
||||
|
||||
async def test_openai_model_creation(self, component_class, default_kwargs):
|
||||
"""Test that the component returns an instance of ChatOpenAI for OpenAI provider."""
|
||||
@ -169,6 +231,66 @@ class TestLanguageModelComponent(ComponentTestBaseWithoutClient):
|
||||
with pytest.raises(ValueError, match="Google API key is required when using Google provider"):
|
||||
component.build_model()
|
||||
|
||||
async def test_ollama_model_creation(self, component_class, default_kwargs):
|
||||
"""Test that the component returns an instance of ChatOllama for Ollama provider."""
|
||||
component = component_class(**default_kwargs)
|
||||
component.provider = "Ollama"
|
||||
component.model_name = "llama2"
|
||||
component.ollama_base_url = "http://localhost:11434"
|
||||
component.temperature = 0.5
|
||||
component.stream = False
|
||||
|
||||
# We should get a ChatOllama instance
|
||||
model = component.build_model()
|
||||
assert isinstance(model, ChatOllama)
|
||||
assert model.model == "llama2"
|
||||
assert model.temperature == 0.5
|
||||
|
||||
async def test_build_model_ibm_watsonx_missing_api_key(self, component_class, default_kwargs):
|
||||
component = component_class(**default_kwargs)
|
||||
component.provider = "IBM watsonx.ai"
|
||||
component.api_key = None
|
||||
|
||||
with pytest.raises(ValueError, match=r"IBM API key is required when using IBM watsonx\.ai provider"):
|
||||
component.build_model()
|
||||
|
||||
async def test_build_model_ibm_watsonx_missing_base_url(self, component_class, default_kwargs):
|
||||
component = component_class(**default_kwargs)
|
||||
component.provider = "IBM watsonx.ai"
|
||||
component.api_key = "test-key"
|
||||
component.base_url_ibm_watsonx = None
|
||||
|
||||
expected_error = r"IBM watsonx API Endpoint is required when using IBM watsonx\.ai provider"
|
||||
with pytest.raises(ValueError, match=expected_error):
|
||||
component.build_model()
|
||||
|
||||
async def test_build_model_ibm_watsonx_missing_project_id(self, component_class, default_kwargs):
|
||||
component = component_class(**default_kwargs)
|
||||
component.provider = "IBM watsonx.ai"
|
||||
component.api_key = "test-key"
|
||||
component.base_url_ibm_watsonx = "https://us-south.ml.cloud.ibm.com"
|
||||
component.project_id = None
|
||||
|
||||
with pytest.raises(ValueError, match=r"IBM watsonx Project ID is required when using IBM watsonx\.ai provider"):
|
||||
component.build_model()
|
||||
|
||||
async def test_build_model_ollama_missing_base_url(self, component_class, default_kwargs):
|
||||
component = component_class(**default_kwargs)
|
||||
component.provider = "Ollama"
|
||||
component.ollama_base_url = None
|
||||
|
||||
with pytest.raises(ValueError, match="Ollama API URL is required when using Ollama provider"):
|
||||
component.build_model()
|
||||
|
||||
async def test_build_model_ollama_missing_model_name(self, component_class, default_kwargs):
|
||||
component = component_class(**default_kwargs)
|
||||
component.provider = "Ollama"
|
||||
component.ollama_base_url = "http://localhost:11434"
|
||||
component.model_name = None
|
||||
|
||||
with pytest.raises(ValueError, match="Model name is required when using Ollama provider"):
|
||||
component.build_model()
|
||||
|
||||
async def test_build_model_unknown_provider(self, component_class, default_kwargs):
|
||||
component = component_class(**default_kwargs)
|
||||
component.provider = "Unknown"
|
||||
|
||||
4
src/frontend/package-lock.json
generated
4
src/frontend/package-lock.json
generated
@ -1,12 +1,12 @@
|
||||
{
|
||||
"name": "langflow",
|
||||
"version": "1.6.7",
|
||||
"version": "1.7.0",
|
||||
"lockfileVersion": 3,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "langflow",
|
||||
"version": "1.6.7",
|
||||
"version": "1.7.0",
|
||||
"dependencies": {
|
||||
"@chakra-ui/number-input": "^2.1.2",
|
||||
"@headlessui/react": "^2.0.4",
|
||||
|
||||
File diff suppressed because one or more lines are too long
@ -1,7 +1,12 @@
|
||||
from typing import Any
|
||||
from urllib.parse import urljoin
|
||||
|
||||
import requests
|
||||
from langchain_anthropic import ChatAnthropic
|
||||
from langchain_ibm import ChatWatsonx
|
||||
from langchain_ollama import ChatOllama
|
||||
from langchain_openai import ChatOpenAI
|
||||
from pydantic.v1 import SecretStr
|
||||
|
||||
from lfx.base.models.anthropic_constants import ANTHROPIC_MODELS
|
||||
from lfx.base.models.google_generative_ai_constants import GOOGLE_GENERATIVE_AI_MODELS
|
||||
@ -10,9 +15,22 @@ from lfx.base.models.model import LCModelComponent
|
||||
from lfx.base.models.openai_constants import OPENAI_CHAT_MODEL_NAMES, OPENAI_REASONING_MODEL_NAMES
|
||||
from lfx.field_typing import LanguageModel
|
||||
from lfx.field_typing.range_spec import RangeSpec
|
||||
from lfx.inputs.inputs import BoolInput
|
||||
from lfx.inputs.inputs import BoolInput, MessageTextInput, StrInput
|
||||
from lfx.io import DropdownInput, MessageInput, MultilineInput, SecretStrInput, SliderInput
|
||||
from lfx.log.logger import logger
|
||||
from lfx.schema.dotdict import dotdict
|
||||
from lfx.utils.util import transform_localhost_url
|
||||
|
||||
# IBM watsonx.ai constants
|
||||
IBM_WATSONX_DEFAULT_MODELS = ["ibm/granite-3-2b-instruct", "ibm/granite-3-8b-instruct", "ibm/granite-13b-instruct-v2"]
|
||||
IBM_WATSONX_URLS = [
|
||||
"https://us-south.ml.cloud.ibm.com",
|
||||
"https://eu-de.ml.cloud.ibm.com",
|
||||
"https://eu-gb.ml.cloud.ibm.com",
|
||||
"https://au-syd.ml.cloud.ibm.com",
|
||||
"https://jp-tok.ml.cloud.ibm.com",
|
||||
"https://ca-tor.ml.cloud.ibm.com",
|
||||
]
|
||||
|
||||
|
||||
class LanguageModelComponent(LCModelComponent):
|
||||
@ -23,15 +41,58 @@ class LanguageModelComponent(LCModelComponent):
|
||||
category = "models"
|
||||
priority = 0 # Set priority to 0 to make it appear first
|
||||
|
||||
@staticmethod
|
||||
def fetch_ibm_models(base_url: str) -> list[str]:
|
||||
"""Fetch available models from the watsonx.ai API."""
|
||||
try:
|
||||
endpoint = f"{base_url}/ml/v1/foundation_model_specs"
|
||||
params = {"version": "2024-09-16", "filters": "function_text_chat,!lifecycle_withdrawn"}
|
||||
response = requests.get(endpoint, params=params, timeout=10)
|
||||
response.raise_for_status()
|
||||
data = response.json()
|
||||
models = [model["model_id"] for model in data.get("resources", [])]
|
||||
return sorted(models)
|
||||
except Exception: # noqa: BLE001
|
||||
logger.exception("Error fetching IBM watsonx models. Using default models.")
|
||||
return IBM_WATSONX_DEFAULT_MODELS
|
||||
|
||||
@staticmethod
|
||||
def fetch_ollama_models(base_url: str) -> list[str]:
|
||||
"""Fetch available models from the Ollama API."""
|
||||
try:
|
||||
# Strip /v1 suffix if present, as Ollama API endpoints are at root level
|
||||
base_url = base_url.rstrip("/").removesuffix("/v1")
|
||||
if not base_url.endswith("/"):
|
||||
base_url = base_url + "/"
|
||||
base_url = transform_localhost_url(base_url)
|
||||
|
||||
# Ollama REST API to return models
|
||||
tags_url = urljoin(base_url, "api/tags")
|
||||
|
||||
response = requests.get(tags_url, timeout=10)
|
||||
response.raise_for_status()
|
||||
data = response.json()
|
||||
models = [model["name"] for model in data.get("models", [])]
|
||||
return sorted(models)
|
||||
except Exception: # noqa: BLE001
|
||||
logger.exception("Error fetching Ollama models. Returning empty list.")
|
||||
return []
|
||||
|
||||
inputs = [
|
||||
DropdownInput(
|
||||
name="provider",
|
||||
display_name="Model Provider",
|
||||
options=["OpenAI", "Anthropic", "Google"],
|
||||
options=["OpenAI", "Anthropic", "Google", "IBM watsonx.ai", "Ollama"],
|
||||
value="OpenAI",
|
||||
info="Select the model provider",
|
||||
real_time_refresh=True,
|
||||
options_metadata=[{"icon": "OpenAI"}, {"icon": "Anthropic"}, {"icon": "GoogleGenerativeAI"}],
|
||||
options_metadata=[
|
||||
{"icon": "OpenAI"},
|
||||
{"icon": "Anthropic"},
|
||||
{"icon": "GoogleGenerativeAI"},
|
||||
{"icon": "WatsonxAI"},
|
||||
{"icon": "Ollama"},
|
||||
],
|
||||
),
|
||||
DropdownInput(
|
||||
name="model_name",
|
||||
@ -49,6 +110,30 @@ class LanguageModelComponent(LCModelComponent):
|
||||
show=True,
|
||||
real_time_refresh=True,
|
||||
),
|
||||
DropdownInput(
|
||||
name="base_url_ibm_watsonx",
|
||||
display_name="watsonx API Endpoint",
|
||||
info="The base URL of the API (IBM watsonx.ai only)",
|
||||
options=IBM_WATSONX_URLS,
|
||||
value=IBM_WATSONX_URLS[0],
|
||||
show=False,
|
||||
real_time_refresh=True,
|
||||
),
|
||||
StrInput(
|
||||
name="project_id",
|
||||
display_name="watsonx Project ID",
|
||||
info="The project ID associated with the foundation model (IBM watsonx.ai only)",
|
||||
show=False,
|
||||
required=False,
|
||||
),
|
||||
MessageTextInput(
|
||||
name="ollama_base_url",
|
||||
display_name="Ollama API URL",
|
||||
info="Endpoint of the Ollama API (Ollama only). Defaults to http://localhost:11434",
|
||||
value="http://localhost:11434",
|
||||
show=False,
|
||||
real_time_refresh=True,
|
||||
),
|
||||
MessageInput(
|
||||
name="input_value",
|
||||
display_name="Input",
|
||||
@ -118,6 +203,52 @@ class LanguageModelComponent(LCModelComponent):
|
||||
streaming=stream,
|
||||
google_api_key=self.api_key,
|
||||
)
|
||||
if provider == "IBM watsonx.ai":
|
||||
if not self.api_key:
|
||||
msg = "IBM API key is required when using IBM watsonx.ai provider"
|
||||
raise ValueError(msg)
|
||||
if not self.base_url_ibm_watsonx:
|
||||
msg = "IBM watsonx API Endpoint is required when using IBM watsonx.ai provider"
|
||||
raise ValueError(msg)
|
||||
if not self.project_id:
|
||||
msg = "IBM watsonx Project ID is required when using IBM watsonx.ai provider"
|
||||
raise ValueError(msg)
|
||||
return ChatWatsonx(
|
||||
apikey=SecretStr(self.api_key).get_secret_value(),
|
||||
url=self.base_url_ibm_watsonx,
|
||||
project_id=self.project_id,
|
||||
model_id=model_name,
|
||||
params={
|
||||
"temperature": temperature,
|
||||
},
|
||||
streaming=stream,
|
||||
)
|
||||
if provider == "Ollama":
|
||||
if not self.ollama_base_url:
|
||||
msg = "Ollama API URL is required when using Ollama provider"
|
||||
raise ValueError(msg)
|
||||
if not model_name:
|
||||
msg = "Model name is required when using Ollama provider"
|
||||
raise ValueError(msg)
|
||||
|
||||
transformed_base_url = transform_localhost_url(self.ollama_base_url)
|
||||
|
||||
# Check if URL contains /v1 suffix (OpenAI-compatible mode)
|
||||
if transformed_base_url and transformed_base_url.rstrip("/").endswith("/v1"):
|
||||
# Strip /v1 suffix and log warning
|
||||
transformed_base_url = transformed_base_url.rstrip("/").removesuffix("/v1")
|
||||
logger.warning(
|
||||
"Detected '/v1' suffix in base URL. The Ollama component uses the native Ollama API, "
|
||||
"not the OpenAI-compatible API. The '/v1' suffix has been automatically removed. "
|
||||
"If you want to use the OpenAI-compatible API, please use the OpenAI component instead. "
|
||||
"Learn more at https://docs.ollama.com/openai#openai-compatibility"
|
||||
)
|
||||
|
||||
return ChatOllama(
|
||||
base_url=transformed_base_url,
|
||||
model=model_name,
|
||||
temperature=temperature,
|
||||
)
|
||||
msg = f"Unknown provider: {provider}"
|
||||
raise ValueError(msg)
|
||||
|
||||
@ -127,14 +258,71 @@ class LanguageModelComponent(LCModelComponent):
|
||||
build_config["model_name"]["options"] = OPENAI_CHAT_MODEL_NAMES + OPENAI_REASONING_MODEL_NAMES
|
||||
build_config["model_name"]["value"] = OPENAI_CHAT_MODEL_NAMES[0]
|
||||
build_config["api_key"]["display_name"] = "OpenAI API Key"
|
||||
build_config["api_key"]["show"] = True
|
||||
build_config["base_url_ibm_watsonx"]["show"] = False
|
||||
build_config["project_id"]["show"] = False
|
||||
build_config["ollama_base_url"]["show"] = False
|
||||
elif field_value == "Anthropic":
|
||||
build_config["model_name"]["options"] = ANTHROPIC_MODELS
|
||||
build_config["model_name"]["value"] = ANTHROPIC_MODELS[0]
|
||||
build_config["api_key"]["display_name"] = "Anthropic API Key"
|
||||
build_config["api_key"]["show"] = True
|
||||
build_config["base_url_ibm_watsonx"]["show"] = False
|
||||
build_config["project_id"]["show"] = False
|
||||
build_config["ollama_base_url"]["show"] = False
|
||||
elif field_value == "Google":
|
||||
build_config["model_name"]["options"] = GOOGLE_GENERATIVE_AI_MODELS
|
||||
build_config["model_name"]["value"] = GOOGLE_GENERATIVE_AI_MODELS[0]
|
||||
build_config["api_key"]["display_name"] = "Google API Key"
|
||||
build_config["api_key"]["show"] = True
|
||||
build_config["base_url_ibm_watsonx"]["show"] = False
|
||||
build_config["project_id"]["show"] = False
|
||||
build_config["ollama_base_url"]["show"] = False
|
||||
elif field_value == "IBM watsonx.ai":
|
||||
build_config["model_name"]["options"] = IBM_WATSONX_DEFAULT_MODELS
|
||||
build_config["model_name"]["value"] = IBM_WATSONX_DEFAULT_MODELS[0]
|
||||
build_config["api_key"]["display_name"] = "IBM API Key"
|
||||
build_config["api_key"]["show"] = True
|
||||
build_config["base_url_ibm_watsonx"]["show"] = True
|
||||
build_config["project_id"]["show"] = True
|
||||
build_config["ollama_base_url"]["show"] = False
|
||||
elif field_value == "Ollama":
|
||||
# Fetch Ollama models from the API
|
||||
ollama_url = build_config["ollama_base_url"].get("value", "http://localhost:11434")
|
||||
models = self.fetch_ollama_models(base_url=ollama_url)
|
||||
build_config["model_name"]["options"] = models
|
||||
build_config["model_name"]["value"] = models[0] if models else ""
|
||||
build_config["api_key"]["show"] = False
|
||||
build_config["base_url_ibm_watsonx"]["show"] = False
|
||||
build_config["project_id"]["show"] = False
|
||||
build_config["ollama_base_url"]["show"] = True
|
||||
elif (
|
||||
field_name == "base_url_ibm_watsonx"
|
||||
and field_value
|
||||
and hasattr(self, "provider")
|
||||
and self.provider == "IBM watsonx.ai"
|
||||
):
|
||||
# Fetch IBM models when base_url changes
|
||||
try:
|
||||
models = self.fetch_ibm_models(base_url=field_value)
|
||||
build_config["model_name"]["options"] = models
|
||||
build_config["model_name"]["value"] = models[0] if models else IBM_WATSONX_DEFAULT_MODELS[0]
|
||||
info_message = f"Updated model options: {len(models)} models found in {field_value}"
|
||||
logger.info(info_message)
|
||||
except Exception: # noqa: BLE001
|
||||
logger.exception("Error updating IBM model options.")
|
||||
elif (
|
||||
field_name == "ollama_base_url" and field_value and hasattr(self, "provider") and self.provider == "Ollama"
|
||||
):
|
||||
# Fetch Ollama models when ollama_base_url changes
|
||||
try:
|
||||
models = self.fetch_ollama_models(base_url=field_value)
|
||||
build_config["model_name"]["options"] = models
|
||||
build_config["model_name"]["value"] = models[0] if models else ""
|
||||
info_message = f"Updated model options: {len(models)} models found in {field_value}"
|
||||
logger.info(info_message)
|
||||
except Exception: # noqa: BLE001
|
||||
logger.exception("Error updating Ollama model options.")
|
||||
elif field_name == "model_name" and field_value.startswith("o1") and self.provider == "OpenAI":
|
||||
# Hide system_message for o1 models - currently unsupported
|
||||
if "system_message" in build_config:
|
||||
|
||||
Reference in New Issue
Block a user