fix: fixed bugs on ollama integration, added ingestion on onboarding (#330)
* Updated ollama components * Changed ollama display name to be correct * Changed prompt of provider validation * removed event dispatched from file upload * Changed onboarding to upload the entire knowledge * Changed default models for ollama
This commit is contained in:
parent
7b635df9d0
commit
b9ea9c99f1
8 changed files with 628 additions and 748 deletions
|
|
@ -31,7 +31,7 @@
|
|||
"list": false,
|
||||
"show": true,
|
||||
"multiline": true,
|
||||
"value": "from typing import Any\nfrom urllib.parse import urljoin\n\nimport httpx\nfrom langchain_ollama import OllamaEmbeddings\n\nfrom lfx.base.models.model import LCModelComponent\nfrom lfx.base.models.ollama_constants import OLLAMA_EMBEDDING_MODELS, URL_LIST\nfrom lfx.field_typing import Embeddings\nfrom lfx.io import DropdownInput, MessageTextInput, Output\n\nHTTP_STATUS_OK = 200\n\n\nclass OllamaEmbeddingsComponent(LCModelComponent):\n display_name: str = \"Ollama Embeddings\"\n description: str = \"Generate embeddings using Ollama models.\"\n documentation = \"https://python.langchain.com/docs/integrations/text_embedding/ollama\"\n icon = \"Ollama\"\n name = \"OllamaEmbeddings\"\n\n inputs = [\n DropdownInput(\n name=\"model_name\",\n display_name=\"Ollama Model\",\n value=\"\",\n options=[],\n real_time_refresh=True,\n refresh_button=True,\n combobox=True,\n required=True,\n ),\n MessageTextInput(\n name=\"base_url\",\n display_name=\"Ollama Base URL\",\n value=\"\",\n required=True,\n ),\n ]\n\n outputs = [\n Output(display_name=\"Embeddings\", name=\"embeddings\", method=\"build_embeddings\"),\n ]\n\n def build_embeddings(self) -> Embeddings:\n try:\n output = OllamaEmbeddings(model=self.model_name, base_url=self.base_url)\n except Exception as e:\n msg = (\n \"Unable to connect to the Ollama API. \",\n \"Please verify the base URL, ensure the relevant Ollama model is pulled, and try again.\",\n )\n raise ValueError(msg) from e\n return output\n\n async def update_build_config(self, build_config: dict, field_value: Any, field_name: str | None = None):\n if field_name in {\"base_url\", \"model_name\"} and not await self.is_valid_ollama_url(field_value):\n # Check if any URL in the list is valid\n valid_url = \"\"\n for url in URL_LIST:\n if await self.is_valid_ollama_url(url):\n valid_url = url\n break\n build_config[\"base_url\"][\"value\"] = valid_url\n if field_name in {\"model_name\", \"base_url\", \"tool_model_enabled\"}:\n if await self.is_valid_ollama_url(self.base_url):\n build_config[\"model_name\"][\"options\"] = await self.get_model(self.base_url)\n elif await self.is_valid_ollama_url(build_config[\"base_url\"].get(\"value\", \"\")):\n build_config[\"model_name\"][\"options\"] = await self.get_model(build_config[\"base_url\"].get(\"value\", \"\"))\n else:\n build_config[\"model_name\"][\"options\"] = []\n\n return build_config\n\n async def get_model(self, base_url_value: str) -> list[str]:\n \"\"\"Get the model names from Ollama.\"\"\"\n model_ids = []\n try:\n url = urljoin(base_url_value, \"/api/tags\")\n async with httpx.AsyncClient() as client:\n response = await client.get(url)\n response.raise_for_status()\n data = response.json()\n\n model_ids = [model[\"name\"] for model in data.get(\"models\", [])]\n # this to ensure that not embedding models are included.\n # not even the base models since models can have 1b 2b etc\n # handles cases when embeddings models have tags like :latest - etc.\n model_ids = [\n model\n for model in model_ids\n if any(model.startswith(f\"{embedding_model}\") for embedding_model in OLLAMA_EMBEDDING_MODELS)\n ]\n\n except (ImportError, ValueError, httpx.RequestError) as e:\n msg = \"Could not get model names from Ollama.\"\n raise ValueError(msg) from e\n\n return model_ids\n\n async def is_valid_ollama_url(self, url: str) -> bool:\n try:\n async with httpx.AsyncClient() as client:\n return (await client.get(f\"{url}/api/tags\")).status_code == HTTP_STATUS_OK\n except httpx.RequestError:\n return False\n",
|
||||
"value": "from typing import Any\nfrom urllib.parse import urljoin\n\nimport httpx\nfrom langchain_ollama import OllamaEmbeddings\n\nfrom lfx.base.models.model import LCModelComponent\nfrom lfx.base.models.ollama_constants import OLLAMA_EMBEDDING_MODELS\nfrom lfx.field_typing import Embeddings\nfrom lfx.io import DropdownInput, MessageTextInput, Output\nfrom lfx.utils.util import transform_localhost_url\n\nHTTP_STATUS_OK = 200\n\n\nclass OllamaEmbeddingsComponent(LCModelComponent):\n display_name: str = \"Ollama Embeddings\"\n description: str = \"Generate embeddings using Ollama models.\"\n documentation = \"https://python.langchain.com/docs/integrations/text_embedding/ollama\"\n icon = \"Ollama\"\n name = \"OllamaEmbeddings\"\n\n inputs = [\n DropdownInput(\n name=\"model_name\",\n display_name=\"Ollama Model\",\n value=\"\",\n options=[],\n real_time_refresh=True,\n refresh_button=True,\n combobox=True,\n required=True,\n ),\n MessageTextInput(\n name=\"base_url\",\n display_name=\"Ollama Base URL\",\n value=\"\",\n required=True,\n ),\n ]\n\n outputs = [\n Output(display_name=\"Embeddings\", name=\"embeddings\", method=\"build_embeddings\"),\n ]\n\n def build_embeddings(self) -> Embeddings:\n transformed_base_url = transform_localhost_url(self.base_url)\n try:\n output = OllamaEmbeddings(model=self.model_name, base_url=transformed_base_url)\n except Exception as e:\n msg = (\n \"Unable to connect to the Ollama API. \",\n \"Please verify the base URL, ensure the relevant Ollama model is pulled, and try again.\",\n )\n raise ValueError(msg) from e\n return output\n\n async def update_build_config(self, build_config: dict, _field_value: Any, field_name: str | None = None):\n if field_name in {\"base_url\", \"model_name\"} and not await self.is_valid_ollama_url(self.base_url):\n msg = \"Ollama is not running on the provided base URL. Please start Ollama and try again.\"\n raise ValueError(msg)\n if field_name in {\"model_name\", \"base_url\", \"tool_model_enabled\"}:\n if await self.is_valid_ollama_url(self.base_url):\n build_config[\"model_name\"][\"options\"] = await self.get_model(self.base_url)\n else:\n build_config[\"model_name\"][\"options\"] = []\n\n return build_config\n\n async def get_model(self, base_url_value: str) -> list[str]:\n \"\"\"Get the model names from Ollama.\"\"\"\n model_ids = []\n try:\n base_url_value = transform_localhost_url(base_url_value)\n url = urljoin(base_url_value, \"/api/tags\")\n async with httpx.AsyncClient() as client:\n response = await client.get(url)\n response.raise_for_status()\n data = response.json()\n\n model_ids = [model[\"name\"] for model in data.get(\"models\", [])]\n # this to ensure that not embedding models are included.\n # not even the base models since models can have 1b 2b etc\n # handles cases when embeddings models have tags like :latest - etc.\n model_ids = [\n model\n for model in model_ids\n if any(model.startswith(f\"{embedding_model}\") for embedding_model in OLLAMA_EMBEDDING_MODELS)\n ]\n\n except (ImportError, ValueError, httpx.RequestError) as e:\n msg = \"Could not get model names from Ollama.\"\n raise ValueError(msg) from e\n\n return model_ids\n\n async def is_valid_ollama_url(self, url: str) -> bool:\n try:\n async with httpx.AsyncClient() as client:\n url = transform_localhost_url(url)\n return (await client.get(f\"{url}/api/tags\")).status_code == HTTP_STATUS_OK\n except httpx.RequestError:\n return False\n",
|
||||
"fileTypes": [],
|
||||
"file_path": "",
|
||||
"password": false,
|
||||
|
|
@ -99,44 +99,27 @@
|
|||
"legacy": false,
|
||||
"edited": false,
|
||||
"metadata": {
|
||||
"keywords": [
|
||||
"model",
|
||||
"llm",
|
||||
"language model",
|
||||
"large language model"
|
||||
],
|
||||
"keywords": ["model", "llm", "language model", "large language model"],
|
||||
"module": "lfx.components.ollama.ollama_embeddings.OllamaEmbeddingsComponent",
|
||||
"code_hash": "c41821735548",
|
||||
"code_hash": "9ef83e250bee",
|
||||
"dependencies": {
|
||||
"total_dependencies": 3,
|
||||
"dependencies": [
|
||||
{
|
||||
"name": "httpx",
|
||||
"version": "0.28.1"
|
||||
},
|
||||
{
|
||||
"name": "langchain_ollama",
|
||||
"version": "0.2.1"
|
||||
},
|
||||
{
|
||||
"name": "lfx",
|
||||
"version": null
|
||||
}
|
||||
{ "name": "httpx", "version": "0.28.1" },
|
||||
{ "name": "langchain_ollama", "version": "0.2.1" },
|
||||
{ "name": "lfx", "version": "0.1.12.dev32" }
|
||||
]
|
||||
}
|
||||
},
|
||||
"tool_mode": false,
|
||||
"last_updated": "2025-09-29T18:40:10.242Z",
|
||||
"last_updated": "2025-10-29T19:54:23.774Z",
|
||||
"official": false
|
||||
},
|
||||
"showNode": true,
|
||||
"type": "OllamaEmbeddings",
|
||||
"id": "OllamaEmbeddings-vnNn8"
|
||||
},
|
||||
"id": "OllamaEmbeddings-vnNn8",
|
||||
"position": {
|
||||
"x": 0,
|
||||
"y": 0
|
||||
"id": "OllamaEmbeddings-3JO8z"
|
||||
},
|
||||
"id": "OllamaEmbeddings-3JO8z",
|
||||
"position": { "x": 0, "y": 0 },
|
||||
"type": "genericNode"
|
||||
}
|
||||
}
|
||||
|
|
|
|||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
|
@ -194,21 +194,6 @@ export async function uploadFile(
|
|||
raw: uploadIngestJson,
|
||||
};
|
||||
|
||||
window.dispatchEvent(
|
||||
new CustomEvent("fileUploaded", {
|
||||
detail: {
|
||||
file,
|
||||
result: {
|
||||
file_id: fileId,
|
||||
file_path: filePath,
|
||||
run: runJson,
|
||||
deletion: deletionJson,
|
||||
unified: true,
|
||||
},
|
||||
},
|
||||
})
|
||||
);
|
||||
|
||||
return result;
|
||||
} catch (error) {
|
||||
window.dispatchEvent(
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@ import { AnimatePresence, motion } from "motion/react";
|
|||
import { type ChangeEvent, useRef, useState } from "react";
|
||||
import { AnimatedProviderSteps } from "@/app/onboarding/components/animated-provider-steps";
|
||||
import { Button } from "@/components/ui/button";
|
||||
import { uploadFileForContext } from "@/lib/upload-utils";
|
||||
import { uploadFile } from "@/lib/upload-utils";
|
||||
|
||||
interface OnboardingUploadProps {
|
||||
onComplete: () => void;
|
||||
|
|
@ -29,7 +29,7 @@ const OnboardingUpload = ({ onComplete }: OnboardingUploadProps) => {
|
|||
setIsUploading(true);
|
||||
try {
|
||||
setCurrentStep(0);
|
||||
await uploadFileForContext(file);
|
||||
await uploadFile(file, true);
|
||||
console.log("Document uploaded successfully");
|
||||
} catch (error) {
|
||||
console.error("Upload failed", (error as Error).message);
|
||||
|
|
|
|||
|
|
@ -110,7 +110,7 @@ async def _test_openai_completion_with_tools(api_key: str, llm_model: str) -> No
|
|||
payload = {
|
||||
"model": llm_model,
|
||||
"messages": [
|
||||
{"role": "user", "content": "What's the weather like?"}
|
||||
{"role": "user", "content": "What tools do you have available?"}
|
||||
],
|
||||
"tools": [
|
||||
{
|
||||
|
|
@ -233,7 +233,7 @@ async def _test_watsonx_completion_with_tools(
|
|||
"model_id": llm_model,
|
||||
"project_id": project_id,
|
||||
"messages": [
|
||||
{"role": "user", "content": "What's the weather like?"}
|
||||
{"role": "user", "content": "What tools do you have available?"}
|
||||
],
|
||||
"tools": [
|
||||
{
|
||||
|
|
@ -356,7 +356,7 @@ async def _test_ollama_completion_with_tools(llm_model: str, endpoint: str) -> N
|
|||
payload = {
|
||||
"model": llm_model,
|
||||
"messages": [
|
||||
{"role": "user", "content": "What's the weather like?"}
|
||||
{"role": "user", "content": "What tools do you have available?"}
|
||||
],
|
||||
"tools": [
|
||||
{
|
||||
|
|
|
|||
|
|
@ -562,7 +562,7 @@ WATSONX_LLM_COMPONENT_DISPLAY_NAME = os.getenv(
|
|||
)
|
||||
|
||||
OLLAMA_EMBEDDING_COMPONENT_DISPLAY_NAME = os.getenv(
|
||||
"OLLAMA_EMBEDDING_COMPONENT_DISPLAY_NAME", "Ollama Model"
|
||||
"OLLAMA_EMBEDDING_COMPONENT_DISPLAY_NAME", "Ollama Embeddings"
|
||||
)
|
||||
OLLAMA_LLM_COMPONENT_DISPLAY_NAME = os.getenv("OLLAMA_LLM_COMPONENT_DISPLAY_NAME", "Ollama")
|
||||
|
||||
|
|
|
|||
|
|
@ -182,7 +182,7 @@ class ModelsService:
|
|||
{
|
||||
"value": model_name,
|
||||
"label": model_name,
|
||||
"default": False,
|
||||
"default": "nomic-embed-text" in model_name.lower(),
|
||||
}
|
||||
)
|
||||
elif not is_embedding and has_completion and has_tools:
|
||||
|
|
@ -191,7 +191,7 @@ class ModelsService:
|
|||
{
|
||||
"value": model_name,
|
||||
"label": model_name,
|
||||
"default": "llama3" in model_name.lower(),
|
||||
"default": "gpt-oss" in model_name.lower(),
|
||||
}
|
||||
)
|
||||
except Exception as e:
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue