diff --git a/README.md b/README.md index 4f276eb95..7ba5d68b0 100644 --- a/README.md +++ b/README.md @@ -61,6 +61,48 @@ web-ontogpt NOTE: We do not recommend hosting this webapp publicly without authentication. +## Model APIs + +OntoGPT uses the `litellm` package () to interface with LLMs. + +This means most APIs are supported, including OpenAI, Azure, Anthropic, Mistral, Replicate, and beyond. + +The model name to use may be found from the command `ontogpt list-models` - use the name in the first column with the `--model` option. + +In most cases, this will require setting the API key for a particular service as above: + +```bash +runoak set-apikey -e anthropic-key +``` + +Some endpoints, such as OpenAI models through Azure, require setting additional details. These may be set similarly: + +```bash +runoak set-apikey -e azure-key +runoak set-apikey -e azure-base +runoak set-apikey -e azure-version +``` + +These details may also be set as environment variables as follows: + +```bash +export AZURE_API_KEY="my-azure-api-key" +export AZURE_API_BASE="https://example-endpoint.openai.azure.com" +export AZURE_API_VERSION="2023-05-15" +``` + +## Open Models + +Open LLMs may be retrieved and run through the `ollama` package (). + +You will need to install `ollama` (see the [GitHub repo](https://github.com/ollama/ollama)), and you may need to start it as a service with a command like `ollama serve` or `sudo systemctl start ollama`. + +Then retrieve a model with `ollama pull `, e.g., `ollama pull llama3`. + +The model may then be used in OntoGPT by prefixing its name with `ollama/`, e.g., `ollama/llama3`, along with the `--model` option. + +Some ollama models may not be listed in `ontogpt list-models` but the full list of downloaded LLMs can be seen with `ollama list` command. + ## Evaluations OntoGPT's functions have been evaluated on test data. Please see the full documentation for details on these evaluations and how to reproduce them. @@ -71,15 +113,15 @@ OntoGPT's functions have been evaluated on test data. Please see the full docume ## Tutorials and Presentations -- Presentation: "Staying grounded: assembling structured biological knowledge with help from large language models" - presented by Harry Caufield as part of the AgBioData Consortium webinar series (September 2023) - - [Slides](https://docs.google.com/presentation/d/1rMQVWaMju-ucYFif5nx4Xv3bNX2SVI_w89iBIT1bkV4/edit?usp=sharing) - - [Video](https://www.youtube.com/watch?v=z38lI6WyBsY) -- Presentation: "Transforming unstructured biomedical texts with large language models" - presented by Harry Caufield as part of the BOSC track at ISMB/ECCB 2023 (July 2023) - - [Slides](https://docs.google.com/presentation/d/1LsOTKi-rXYczL9vUTHB1NDkaEqdA9u3ZFC5ANa0x1VU/edit?usp=sharing) - - [Video](https://www.youtube.com/watch?v=a34Yjz5xPp4) -- Presentation: "OntoGPT: A framework for working with ontologies and large language models" - talk by Chris Mungall at Joint Food Ontology Workgroup (May 2023) - - [Slides](https://docs.google.com/presentation/d/1CosJJe8SqwyALyx85GWkw9eOT43B4HwDlAY2CmkmJgU/edit) - - [Video](https://www.youtube.com/watch?v=rt3wobA9hEs&t=1955s) +* Presentation: "Staying grounded: assembling structured biological knowledge with help from large language models" - presented by Harry Caufield as part of the AgBioData Consortium webinar series (September 2023) + * [Slides](https://docs.google.com/presentation/d/1rMQVWaMju-ucYFif5nx4Xv3bNX2SVI_w89iBIT1bkV4/edit?usp=sharing) + * [Video](https://www.youtube.com/watch?v=z38lI6WyBsY) +* Presentation: "Transforming unstructured biomedical texts with large language models" - presented by Harry Caufield as part of the BOSC track at ISMB/ECCB 2023 (July 2023) + * [Slides](https://docs.google.com/presentation/d/1LsOTKi-rXYczL9vUTHB1NDkaEqdA9u3ZFC5ANa0x1VU/edit?usp=sharing) + * [Video](https://www.youtube.com/watch?v=a34Yjz5xPp4) +* Presentation: "OntoGPT: A framework for working with ontologies and large language models" - talk by Chris Mungall at Joint Food Ontology Workgroup (May 2023) + * [Slides](https://docs.google.com/presentation/d/1CosJJe8SqwyALyx85GWkw9eOT43B4HwDlAY2CmkmJgU/edit) + * [Video](https://www.youtube.com/watch?v=rt3wobA9hEs&t=1955s) ## Citation diff --git a/docs/index.md b/docs/index.md index 14ead8c9e..a1022b3be 100644 --- a/docs/index.md +++ b/docs/index.md @@ -1,6 +1,6 @@ # Introduction -_OntoGPT_ is a Python package for extracting structured information from text with large language models (LLMs), _instruction prompts_, and ontology-based grounding. It works well with OpenAI's GPT models as well as a selection of other LLMs. OntoGPT's output can be used for general-purpose natural language tasks (e.g., named entity recognition and relation extraction), summarization, knowledge base and knowledge graph construction, and more. +_OntoGPT_ is a Python package for extracting structured information from text with large language models (LLMs), _instruction prompts_, and ontology-based grounding. It works well with OpenAI's GPT models as well as a selection of other LLMs. OntoGPT's output can be used for general-purpose natural language tasks (e.g., named entity recognition and relation extraction), summarization, knowledge base and knowledge graph construction, and more. ## Methods diff --git a/docs/operation.md b/docs/operation.md index ce4010d22..ef20b4958 100644 --- a/docs/operation.md +++ b/docs/operation.md @@ -36,7 +36,7 @@ OntoGPT is intended to be used for information extraction. The following example #### Working Mechanism -1. You provide an arbitrary data model, describing the structure you want to extract text into. This can be nested (but see limitations below). The predefined [templates](src/ontogpt/templates/) may be used. +1. You provide an arbitrary data model, describing the structure you want to extract text into. This can be nested (but see limitations below). The predefined templates may be used. 2. Provide your preferred annotations for grounding `NamedEntity` fields 3. OntoGPT will: * Generate a prompt @@ -46,7 +46,7 @@ OntoGPT is intended to be used for information extraction. The following example #### Input -Consider some text from one of the input files being used in the OntoGPT test suite. You can find the text file [here](tests/input/cases/gocam-betacat.txt). You can download the raw file from the GitHub link to that input text file, or copy its contents over into another file, say, `abstract.txt`. An excerpt: +Consider some text from one of the input files being used in the OntoGPT test suite. You can find the text file [here](https://github.com/monarch-initiative/ontogpt/blob/main/tests/input/cases/gocam-betacat.txt). You can download the raw file from the GitHub link to that input text file, or copy its contents over into another file, say, `abstract.txt`. An excerpt: > The cGAS/STING-mediated DNA-sensing signaling pathway is crucial for interferon (IFN) production and host antiviral @@ -62,7 +62,7 @@ Consider some text from one of the input files being used in the OntoGPT test su > ... > ... -We can extract knowledge from the above text this into the [GO pathway datamodel](src/ontogpt/templates/gocam.yaml) by running the following command: +We can extract knowledge from the above text this into the [GO pathway datamodel](https://github.com/monarch-initiative/ontogpt/blob/main/src/ontogpt/templates/gocam.yaml) by running the following command: #### Command @@ -70,7 +70,9 @@ We can extract knowledge from the above text this into the [GO pathway datamodel ontogpt extract -t gocam.GoCamAnnotations -i ~/path/to/abstract.txt ``` -Note: The value accepted by the `-t` / `--template` argument is the base name of one of the LinkML schema / data model which can be found in the [templates](src/ontogpt/templates/) folder. +Note: The value accepted by the `-t` / `--template` argument is the base name of one of the LinkML schema / data model available to OntoGPT. + +Use the command `ontogpt list-templates` to see all templates. Use the name in the first column with the `--template` option. Or, if you create your own schema (see the page on [custom schemas](custom.md)), you may pass the path to the .yaml file. @@ -104,18 +106,20 @@ gene_functions: #### Local Models -To use a local model, specify it with the `-m` or `--model` option. +To use a local model, download it through `ollama` (see the setup page for more details: ) + +Then specify it with the `-m` or `--model` option. Example: ```bash -ontogpt extract -t drug -i ~/path/to/abstract.txt -m nous-hermes-13b +ontogpt extract -t drug -i ~/path/to/abstract.txt -m ollama/llama3 ``` -See the list of all available models with this command: +See the list of all downloaded models with this command: ```bash -ontogpt list-models +ollama list ``` -When specifying a local model for the first time, it will be downloaded to your local system. +Note that models can and will vary in performance and larger models will not always perform more accurately or more efficiently. diff --git a/docs/setup.md b/docs/setup.md index 687d5bb02..fc318dbb1 100644 --- a/docs/setup.md +++ b/docs/setup.md @@ -97,3 +97,5 @@ This may require a command like `ollama serve` or `sudo systemctl start ollama`. Then retrieve a model with `ollama pull `, e.g., `ollama pull llama3`. The model may then be used in OntoGPT by prefixing its name with `ollama/`, e.g., `ollama/llama3`, along with the `--model` option. + +See the list of all downloaded LLMs with the `ollama list` command. diff --git a/mkdocs.yml b/mkdocs.yml index f5c75865b..659d5ca59 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -37,6 +37,7 @@ nav: - Troubleshooting: troubleshooting.md - SPIRES Templates: # Note these are autogenerated - Core Upper Level Schema: core/index.md + - Alzheimer's Disease: alzrd/index.md - Biochemical Reactions: reaction/index.md - Biological Processes: biological_process/index.md - Biotic Interactions: biotic_interaction/index.md @@ -49,6 +50,7 @@ nav: - Drugs and Mechanisms: drug/index.md - EMAPA (Mouse Developmental Anatomy Ontology): emapa_simple/index.md - Environmental Samples: environmental_sample/index.md + - Error Analysis: error_analysis/index.md - Figures: figure/index.md - GO Terms: go_terms/index.md - GO Terms (Entities Only): go_simple/index.md @@ -64,7 +66,9 @@ nav: - NMDC Schema Data: nmdc_schema_data/index.md - Ontology Classes: ontology_class/index.md - Ontology Issues: ontology_issue/index.md + - Ontology Usage: onto_usage/index.md - Recipes: recipe/index.md + - STORMS Checklist: storms/index.md - Traits of a Taxon: traits/index.md - Treatments: treatment/index.md - HALO Schema: halo/index.md diff --git a/poetry.lock b/poetry.lock index 688b2be1f..dc1b570bc 100644 --- a/poetry.lock +++ b/poetry.lock @@ -504,17 +504,17 @@ files = [ [[package]] name = "boto3" -version = "1.34.148" +version = "1.34.150" description = "The AWS SDK for Python" optional = false python-versions = ">=3.8" files = [ - {file = "boto3-1.34.148-py3-none-any.whl", hash = "sha256:d63d36e5a34533ba69188d56f96da132730d5e9932c4e11c02d79319cd1afcec"}, - {file = "boto3-1.34.148.tar.gz", hash = "sha256:2058397f0a92c301e3116e9e65fbbc70ea49270c250882d65043d19b7c6e2d17"}, + {file = "boto3-1.34.150-py3-none-any.whl", hash = "sha256:ad648c89a4935590a69341e5430fc42a021489a22de171ee3fd7bb204f9ef0fa"}, + {file = "boto3-1.34.150.tar.gz", hash = "sha256:894b222f7850b870a7ac63d7e378ac36c5c34375da24ddc30e131d9fafe369dc"}, ] [package.dependencies] -botocore = ">=1.34.148,<1.35.0" +botocore = ">=1.34.150,<1.35.0" jmespath = ">=0.7.1,<2.0.0" s3transfer = ">=0.10.0,<0.11.0" @@ -523,13 +523,13 @@ crt = ["botocore[crt] (>=1.21.0,<2.0a0)"] [[package]] name = "botocore" -version = "1.34.148" +version = "1.34.150" description = "Low-level, data-driven core of boto 3." optional = false python-versions = ">=3.8" files = [ - {file = "botocore-1.34.148-py3-none-any.whl", hash = "sha256:9e09428b0bc4d0c1cf5e368dd6ab18eabf6047304060f8b5dd8391677cfe00e6"}, - {file = "botocore-1.34.148.tar.gz", hash = "sha256:258dd95570b43db9fa21cce5426eabaea5867e3a61224157650448b5019d1bbd"}, + {file = "botocore-1.34.150-py3-none-any.whl", hash = "sha256:b988d47f4d502df85befce11a48002421e4e6ea4289997b5e0261bac5fa76ce6"}, + {file = "botocore-1.34.150.tar.gz", hash = "sha256:4d23387e0f076d87b637a2a35c0ff2b8daca16eace36b63ce27f65630c6b375a"}, ] [package.dependencies] @@ -2106,13 +2106,13 @@ socks = ["socksio (==1.*)"] [[package]] name = "huggingface-hub" -version = "0.24.2" +version = "0.24.3" description = "Client library to download and publish models, datasets and other repos on the huggingface.co hub" optional = false python-versions = ">=3.8.0" files = [ - {file = "huggingface_hub-0.24.2-py3-none-any.whl", hash = "sha256:abdf3244d3a274c4b1fbc5c4a1ef700032b3f60ba93cc63e4f036fd082aa2805"}, - {file = "huggingface_hub-0.24.2.tar.gz", hash = "sha256:92be892405d2f6a7a8479016f9a5662354f202b2c6c1ff499609621aed1fae10"}, + {file = "huggingface_hub-0.24.3-py3-none-any.whl", hash = "sha256:69ecce486dd6cdad69937ba76779e893c224a670a9d947636c1d5cbd049e44d8"}, + {file = "huggingface_hub-0.24.3.tar.gz", hash = "sha256:bfdc05cc9b64a0e24e8614a44222698799183268f6b68be209aa2df70cff2cde"}, ] [package.dependencies] @@ -3267,13 +3267,13 @@ requests = "*" [[package]] name = "litellm" -version = "1.42.1" +version = "1.42.5" description = "Library to easily interface with LLM API providers" optional = false python-versions = "!=2.7.*,!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,!=3.6.*,!=3.7.*,>=3.8" files = [ - {file = "litellm-1.42.1-py3-none-any.whl", hash = "sha256:2811bae2f2ecca57c6f389e0cc7580d38248f11ad74543a57be5d13ff8f07c62"}, - {file = "litellm-1.42.1.tar.gz", hash = "sha256:94bf5a2a6a6c87abb21321f8876ad350fb486cbdd3ae3818c16226c19d57dd94"}, + {file = "litellm-1.42.5-py3-none-any.whl", hash = "sha256:c8c2f9e40b5aa1c2dcfcac9adb854b8ac22ce2112825d742d8fce516d26e9a65"}, + {file = "litellm-1.42.5.tar.gz", hash = "sha256:64ea24040751009e70e816e9340c5c82717d9a309f4480e5ece9f3f67328e04e"}, ] [package.dependencies] @@ -3449,13 +3449,13 @@ source = ["Cython (>=3.0.10)"] [[package]] name = "lxml-html-clean" -version = "0.1.1" +version = "0.2.0" description = "HTML cleaner from lxml project" optional = true python-versions = "*" files = [ - {file = "lxml_html_clean-0.1.1-py3-none-any.whl", hash = "sha256:58c04176593c9caf72ec92e033d2f38859e918b3eff0cc0f8051ad27dc2ab8ef"}, - {file = "lxml_html_clean-0.1.1.tar.gz", hash = "sha256:8a644ed01dbbe132fabddb9467f077f6dad12a1d4f3a6a553e280f3815fa46df"}, + {file = "lxml_html_clean-0.2.0-py3-none-any.whl", hash = "sha256:80bdc730b288b8e68f0bf86b99f4bbef129c5ec59b694c6681422be4c1eeb3c5"}, + {file = "lxml_html_clean-0.2.0.tar.gz", hash = "sha256:47c323f39d95d4cbf4956da62929c89a79313074467efaa4821013c97bf95628"}, ] [package.dependencies] @@ -4321,13 +4321,13 @@ tests = ["coverage", "pytest", "unittest-templates"] [[package]] name = "openai" -version = "1.37.0" +version = "1.37.1" description = "The official Python library for the openai API" optional = false python-versions = ">=3.7.1" files = [ - {file = "openai-1.37.0-py3-none-any.whl", hash = "sha256:a903245c0ecf622f2830024acdaa78683c70abb8e9d37a497b851670864c9f73"}, - {file = "openai-1.37.0.tar.gz", hash = "sha256:dc8197fc40ab9d431777b6620d962cc49f4544ffc3011f03ce0a805e6eb54adb"}, + {file = "openai-1.37.1-py3-none-any.whl", hash = "sha256:9a6adda0d6ae8fce02d235c5671c399cfa40d6a281b3628914c7ebf244888ee3"}, + {file = "openai-1.37.1.tar.gz", hash = "sha256:faf87206785a6b5d9e34555d6a3242482a6852bc802e453e2a891f68ee04ce55"}, ] [package.dependencies] @@ -5053,13 +5053,13 @@ jsonasobj = ">=1.2.1" [[package]] name = "pymdown-extensions" -version = "10.8.1" +version = "10.9" description = "Extension pack for Python Markdown." optional = false python-versions = ">=3.8" files = [ - {file = "pymdown_extensions-10.8.1-py3-none-any.whl", hash = "sha256:f938326115884f48c6059c67377c46cf631c733ef3629b6eed1349989d1b30cb"}, - {file = "pymdown_extensions-10.8.1.tar.gz", hash = "sha256:3ab1db5c9e21728dabf75192d71471f8e50f216627e9a1fa9535ecb0231b9940"}, + {file = "pymdown_extensions-10.9-py3-none-any.whl", hash = "sha256:d323f7e90d83c86113ee78f3fe62fc9dee5f56b54d912660703ea1816fed5626"}, + {file = "pymdown_extensions-10.9.tar.gz", hash = "sha256:6ff740bcd99ec4172a938970d42b96128bdc9d4b9bcad72494f29921dc69b753"}, ] [package.dependencies] @@ -5104,19 +5104,19 @@ testing = ["covdefaults (>=2.3)", "pytest (>=8.2.2)", "pytest-cov (>=5)", "pytes [[package]] name = "pyrdfa3" -version = "3.6.2" +version = "3.6.4" description = "pyRdfa distiller/parser library" optional = true -python-versions = ">=3.7" +python-versions = ">=3.8" files = [ - {file = "pyRdfa3-3.6.2-py3-none-any.whl", hash = "sha256:290c2fa966ddd1b45ac94a727da144f5a233ed58c63c370e3d68e6d00b0dee5d"}, - {file = "pyRdfa3-3.6.2.tar.gz", hash = "sha256:73681dab957f60901696767388b956a5769c730bc451da6ffb2f0e36f18314c2"}, + {file = "pyRdfa3-3.6.4-py3-none-any.whl", hash = "sha256:ed11affa5567ab7afdbc939a58f9286a274447f3ab2999c260c56b5c6e87fb2f"}, + {file = "pyrdfa3-3.6.4.tar.gz", hash = "sha256:64712d1a4bf21829652b39715bada6e7c03bcf19cb49f962c190a38f46172243"}, ] [package.dependencies] html5lib = ">=1.1" -rdflib = ">=6.1.1" -requests = ">=2.25.1" +rdflib = ">=7.0.0" +requests = ">=2.32.3" [[package]] name = "pyshex" @@ -5643,20 +5643,22 @@ rdflib-jsonld = "0.6.1" [[package]] name = "recipe-scrapers" -version = "14.58.0" +version = "15.0.0" description = "Python package, scraping recipes from all over the internet" optional = true python-versions = ">=3.8" files = [ - {file = "recipe_scrapers-14.58.0-py3-none-any.whl", hash = "sha256:dfdd059bb8c6dece6ea3f5249326eeb6c92bae75398d67e4784cf1d6b4890af0"}, - {file = "recipe_scrapers-14.58.0.tar.gz", hash = "sha256:c7df2c8d0764c6a62a76d897fb9b1533c3424f04cc33bff242bb21d3925d1441"}, + {file = "recipe_scrapers-15.0.0-py3-none-any.whl", hash = "sha256:705d4e80bd0471f4fd73c584a551ca94f96521fdb1e766614aaebd32014d72c9"}, + {file = "recipe_scrapers-15.0.0.tar.gz", hash = "sha256:d6fc8c5bacb67b571ac1cbaf4ab77e5f338112c107d40062e0a68403d16b8872"}, ] [package.dependencies] beautifulsoup4 = ">=4.12.3" extruct = ">=0.17.0" isodate = ">=0.6.1" -requests = ">=2.31.0" + +[package.extras] +online = ["requests (>=2.31.0)"] [[package]] name = "red-black-tree-mod" @@ -6253,13 +6255,13 @@ win32 = ["pywin32"] [[package]] name = "setuptools" -version = "71.1.0" +version = "72.1.0" description = "Easily download, build, install, upgrade, and uninstall Python packages" optional = false python-versions = ">=3.8" files = [ - {file = "setuptools-71.1.0-py3-none-any.whl", hash = "sha256:33874fdc59b3188304b2e7c80d9029097ea31627180896fb549c578ceb8a0855"}, - {file = "setuptools-71.1.0.tar.gz", hash = "sha256:032d42ee9fb536e33087fb66cac5f840eb9391ed05637b3f2a76a7c8fb477936"}, + {file = "setuptools-72.1.0-py3-none-any.whl", hash = "sha256:5a03e1860cf56bb6ef48ce186b0e557fdba433237481a9a625176c2831be15d1"}, + {file = "setuptools-72.1.0.tar.gz", hash = "sha256:8d243eff56d095e5817f796ede6ae32941278f542e0f941867cc05ae52b162ec"}, ] [package.extras] @@ -6514,49 +6516,49 @@ dev = ["bump2version", "sphinxcontrib-httpdomain", "transifex-client", "wheel"] [[package]] name = "sphinxcontrib-applehelp" -version = "1.0.8" +version = "2.0.0" description = "sphinxcontrib-applehelp is a Sphinx extension which outputs Apple help books" optional = true python-versions = ">=3.9" files = [ - {file = "sphinxcontrib_applehelp-1.0.8-py3-none-any.whl", hash = "sha256:cb61eb0ec1b61f349e5cc36b2028e9e7ca765be05e49641c97241274753067b4"}, - {file = "sphinxcontrib_applehelp-1.0.8.tar.gz", hash = "sha256:c40a4f96f3776c4393d933412053962fac2b84f4c99a7982ba42e09576a70619"}, + {file = "sphinxcontrib_applehelp-2.0.0-py3-none-any.whl", hash = "sha256:4cd3f0ec4ac5dd9c17ec65e9ab272c9b867ea77425228e68ecf08d6b28ddbdb5"}, + {file = "sphinxcontrib_applehelp-2.0.0.tar.gz", hash = "sha256:2f29ef331735ce958efa4734873f084941970894c6090408b079c61b2e1c06d1"}, ] [package.extras] -lint = ["docutils-stubs", "flake8", "mypy"] +lint = ["mypy", "ruff (==0.5.5)", "types-docutils"] standalone = ["Sphinx (>=5)"] test = ["pytest"] [[package]] name = "sphinxcontrib-devhelp" -version = "1.0.6" +version = "2.0.0" description = "sphinxcontrib-devhelp is a sphinx extension which outputs Devhelp documents" optional = true python-versions = ">=3.9" files = [ - {file = "sphinxcontrib_devhelp-1.0.6-py3-none-any.whl", hash = "sha256:6485d09629944511c893fa11355bda18b742b83a2b181f9a009f7e500595c90f"}, - {file = "sphinxcontrib_devhelp-1.0.6.tar.gz", hash = "sha256:9893fd3f90506bc4b97bdb977ceb8fbd823989f4316b28c3841ec128544372d3"}, + {file = "sphinxcontrib_devhelp-2.0.0-py3-none-any.whl", hash = "sha256:aefb8b83854e4b0998877524d1029fd3e6879210422ee3780459e28a1f03a8a2"}, + {file = "sphinxcontrib_devhelp-2.0.0.tar.gz", hash = "sha256:411f5d96d445d1d73bb5d52133377b4248ec79db5c793ce7dbe59e074b4dd1ad"}, ] [package.extras] -lint = ["docutils-stubs", "flake8", "mypy"] +lint = ["mypy", "ruff (==0.5.5)", "types-docutils"] standalone = ["Sphinx (>=5)"] test = ["pytest"] [[package]] name = "sphinxcontrib-htmlhelp" -version = "2.0.6" +version = "2.1.0" description = "sphinxcontrib-htmlhelp is a sphinx extension which renders HTML help files" optional = true python-versions = ">=3.9" files = [ - {file = "sphinxcontrib_htmlhelp-2.0.6-py3-none-any.whl", hash = "sha256:1b9af5a2671a61410a868fce050cab7ca393c218e6205cbc7f590136f207395c"}, - {file = "sphinxcontrib_htmlhelp-2.0.6.tar.gz", hash = "sha256:c6597da06185f0e3b4dc952777a04200611ef563882e0c244d27a15ee22afa73"}, + {file = "sphinxcontrib_htmlhelp-2.1.0-py3-none-any.whl", hash = "sha256:166759820b47002d22914d64a075ce08f4c46818e17cfc9470a9786b759b19f8"}, + {file = "sphinxcontrib_htmlhelp-2.1.0.tar.gz", hash = "sha256:c9e2916ace8aad64cc13a0d233ee22317f2b9025b9cf3295249fa985cc7082e9"}, ] [package.extras] -lint = ["docutils-stubs", "flake8", "mypy"] +lint = ["mypy", "ruff (==0.5.5)", "types-docutils"] standalone = ["Sphinx (>=5)"] test = ["html5lib", "pytest"] @@ -6590,45 +6592,45 @@ test = ["flake8", "mypy", "pytest"] [[package]] name = "sphinxcontrib-qthelp" -version = "1.0.8" +version = "2.0.0" description = "sphinxcontrib-qthelp is a sphinx extension which outputs QtHelp documents" optional = true python-versions = ">=3.9" files = [ - {file = "sphinxcontrib_qthelp-1.0.8-py3-none-any.whl", hash = "sha256:323d6acc4189af76dfe94edd2a27d458902319b60fcca2aeef3b2180c106a75f"}, - {file = "sphinxcontrib_qthelp-1.0.8.tar.gz", hash = "sha256:db3f8fa10789c7a8e76d173c23364bdf0ebcd9449969a9e6a3dd31b8b7469f03"}, + {file = "sphinxcontrib_qthelp-2.0.0-py3-none-any.whl", hash = "sha256:b18a828cdba941ccd6ee8445dbe72ffa3ef8cbe7505d8cd1fa0d42d3f2d5f3eb"}, + {file = "sphinxcontrib_qthelp-2.0.0.tar.gz", hash = "sha256:4fe7d0ac8fc171045be623aba3e2a8f613f8682731f9153bb2e40ece16b9bbab"}, ] [package.extras] -lint = ["docutils-stubs", "flake8", "mypy"] +lint = ["mypy", "ruff (==0.5.5)", "types-docutils"] standalone = ["Sphinx (>=5)"] test = ["defusedxml (>=0.7.1)", "pytest"] [[package]] name = "sphinxcontrib-serializinghtml" -version = "1.1.10" +version = "2.0.0" description = "sphinxcontrib-serializinghtml is a sphinx extension which outputs \"serialized\" HTML files (json and pickle)" optional = true python-versions = ">=3.9" files = [ - {file = "sphinxcontrib_serializinghtml-1.1.10-py3-none-any.whl", hash = "sha256:326369b8df80a7d2d8d7f99aa5ac577f51ea51556ed974e7716cfd4fca3f6cb7"}, - {file = "sphinxcontrib_serializinghtml-1.1.10.tar.gz", hash = "sha256:93f3f5dc458b91b192fe10c397e324f262cf163d79f3282c158e8436a2c4511f"}, + {file = "sphinxcontrib_serializinghtml-2.0.0-py3-none-any.whl", hash = "sha256:6e2cb0eef194e10c27ec0023bfeb25badbbb5868244cf5bc5bdc04e4464bf331"}, + {file = "sphinxcontrib_serializinghtml-2.0.0.tar.gz", hash = "sha256:e9d912827f872c029017a53f0ef2180b327c3f7fd23c87229f7a8e8b70031d4d"}, ] [package.extras] -lint = ["docutils-stubs", "flake8", "mypy"] +lint = ["mypy", "ruff (==0.5.5)", "types-docutils"] standalone = ["Sphinx (>=5)"] test = ["pytest"] [[package]] name = "sphinxcontrib-websupport" -version = "1.2.7" +version = "2.0.0" description = "sphinxcontrib-websupport provides a Python API to easily integrate Sphinx documentation into your Web application" optional = true python-versions = ">=3.9" files = [ - {file = "sphinxcontrib_websupport-1.2.7-py3-none-any.whl", hash = "sha256:2dc179d7f821ebd54f31f93c894ca52435ebc5364e4e4dfb0da834ac119d51fd"}, - {file = "sphinxcontrib_websupport-1.2.7.tar.gz", hash = "sha256:e322802ebfd5fe79368efd864aeb87b063566ae61911dccb2714e28a45ed7561"}, + {file = "sphinxcontrib_websupport-2.0.0-py3-none-any.whl", hash = "sha256:365b4da67e03cc163dc4752ed44b3c4bc334172c8198102135a7eb7945111229"}, + {file = "sphinxcontrib_websupport-2.0.0.tar.gz", hash = "sha256:0b7367d3bac6454b1f97e42aa8c4d4d4a1b756d525fc726ebbe5571e033e79cd"}, ] [package.dependencies] @@ -6637,7 +6639,7 @@ Sphinx = ">=5" sphinxcontrib-serializinghtml = "*" [package.extras] -lint = ["docutils-stubs", "flake8", "mypy"] +lint = ["mypy", "ruff (==0.5.5)", "types-docutils"] test = ["pytest"] whoosh = ["sqlalchemy", "whoosh"] @@ -6836,13 +6838,13 @@ full = ["httpx (>=0.22.0)", "itsdangerous", "jinja2", "python-multipart (>=0.0.7 [[package]] name = "tenacity" -version = "8.5.0" +version = "9.0.0" description = "Retry code until it succeeds" optional = false python-versions = ">=3.8" files = [ - {file = "tenacity-8.5.0-py3-none-any.whl", hash = "sha256:b594c2a5945830c267ce6b79a166228323ed52718f30302c1359836112346687"}, - {file = "tenacity-8.5.0.tar.gz", hash = "sha256:8bc6c0c8a09b31e6cad13c47afbed1a567518250a9a171418582ed8d9c20ca78"}, + {file = "tenacity-9.0.0-py3-none-any.whl", hash = "sha256:93de0c98785b27fcf659856aa9f54bfbd399e29969b0621bc7f762bd441b4539"}, + {file = "tenacity-9.0.0.tar.gz", hash = "sha256:807f37ca97d62aa361264d497b0e31e92b8027044942bfa756160d908320d73b"}, ] [package.extras] diff --git a/pyproject.toml b/pyproject.toml index 705d79d97..2364f58c8 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [tool.poetry] name = "ontogpt" -version = "1.0.0rc2" +version = "1.0.0" description = "OntoGPT" authors = ["Chris Mungall ", "J. Harry Caufield "] license = "BSD-3" diff --git a/src/ontogpt/clients/llm_client.py b/src/ontogpt/clients/llm_client.py index 87815790e..dec2838aa 100644 --- a/src/ontogpt/clients/llm_client.py +++ b/src/ontogpt/clients/llm_client.py @@ -17,6 +17,7 @@ # Just get the part before the slash in each model name SERVICES = {model.split("/")[0] for model in MODELS.keys() if len(model.split("/")) > 1} + @dataclass class LLMClient: @@ -35,6 +36,8 @@ class LLMClient: def __post_init__(self): # Get appropriate API key for the model source # and other details if needed + if self.model.startswith("ollama"): + self.api_key = "" # Don't need an API key if not self.api_key and not self.custom_llm_provider: self.api_key = get_apikey_value("openai") elif self.custom_llm_provider == "anthropic": @@ -109,7 +112,7 @@ def embeddings(self, text: str): ) if response is not None: - payload = response.data[0]['embedding'] + payload = response.data[0]["embedding"] else: logger.error("No response or response is empty.") payload = "" diff --git a/src/ontogpt/webapp/html/form.html b/src/ontogpt/webapp/html/form.html index 2d883d093..ce447018a 100644 --- a/src/ontogpt/webapp/html/form.html +++ b/src/ontogpt/webapp/html/form.html @@ -28,12 +28,29 @@ cursor: pointer; } + .loading { + display: none; + text-align: center; + margin-top: 20px; + } + + .loading img { + width: 50px; + height: 50px; + } + .footer { background-color: #f1f1f1; padding: 20px; text-align: center; } +
@@ -48,7 +65,7 @@

Information Extraction with SPIRES

- Select LLM: + Select LLM (non-GPT models will require ollama to be running):
- + +
+ Loading... +
- This process currently uses the OpenAI API. + GPT models use the OpenAI API and may incur costs.
- Please be patient, can take up to 10s, or longer if ontology resources need to be retrieved. + Please be patient, can take up to 10s, or longer if ontology resources need to be retrieved and/or using large local models.
diff --git a/src/ontogpt/webapp/html/spindoctor/form.html b/src/ontogpt/webapp/html/spindoctor/form.html deleted file mode 100644 index 28d39826a..000000000 --- a/src/ontogpt/webapp/html/spindoctor/form.html +++ /dev/null @@ -1,32 +0,0 @@ - - - - - OntoGPT SPINDOCTOR: Enter genes - - -
-
-
- Select Model: - -
-
- -
- -
- -
- -
- - - diff --git a/src/ontogpt/webapp/html/spindoctor/results.html b/src/ontogpt/webapp/html/spindoctor/results.html deleted file mode 100644 index 8df392d76..000000000 --- a/src/ontogpt/webapp/html/spindoctor/results.html +++ /dev/null @@ -1,15 +0,0 @@ - - - - - SPINDOCTOR: Results - - - - -{{ inner_html|safe }} - - - diff --git a/src/ontogpt/webapp/main.py b/src/ontogpt/webapp/main.py index fea1af849..568192cc3 100644 --- a/src/ontogpt/webapp/main.py +++ b/src/ontogpt/webapp/main.py @@ -26,7 +26,16 @@ for template_id, (_name, description) in all_templates.items(): DATAMODELS[template_id] = f"{description}" -LLM_MODELS = ["gpt-4o", "gpt-4", "gpt-4-turbo", "gpt-3.5-turbo"] +LLM_MODELS = [ + "gpt-4o-mini", + "gpt-4o", + "gpt-4", + "gpt-4-turbo", + "gpt-3.5-turbo", + "ollama/llama2", + "ollama/llama3", + "ollama/orca-mini", +] class Query(BaseModel): @@ -47,15 +56,8 @@ class Query(BaseModel): def get_engine(datamodel: str, llm_model: str): if datamodel not in engines: template_details = get_template_details(template=datamodel) - try: - engines[datamodel] = SPIRESEngine( - model=llm_model, template_details=template_details, model_provider="openai" - ) - except ValueError as e: - print(f"Encountered an error setting up the knowledge engine: {e}") - print("Will fall back to defaults.") - engines[datamodel] = SPIRESEngine( - model="gpt-3.5-turbo", template_details=template_details, model_provider="openai" + engines[datamodel] = SPIRESEngine( + model=llm_model, template_details=template_details ) return engines[datamodel] diff --git a/src/ontogpt/webapp/static/loading.gif b/src/ontogpt/webapp/static/loading.gif new file mode 100755 index 000000000..7c1bf7213 Binary files /dev/null and b/src/ontogpt/webapp/static/loading.gif differ