Repository: spyder-ide/langchain-provider (language: python)

Issue:
Release langchain-provider 0.1.0
Creating this issue in case there are comments/questions for the upcoming release 🚀


Discussion / hints:

Fix patch:
diff --git a/.github/funding.yml b/.github/funding.yml
index 1443e4e..f7beb14 100644
--- a/.github/funding.yml
+++ b/.github/funding.yml
@@ -1,1 +1,1 @@
-open_collective: spyder
\ No newline at end of file
+open_collective: spyder
diff --git a/.github/scripts/generate-without-spyder.py b/.github/scripts/generate-without-spyder.py
deleted file mode 100644
index ff8229c..0000000
--- a/.github/scripts/generate-without-spyder.py
+++ /dev/null
@@ -1,16 +0,0 @@
-#!/usr/bin/env python
-#
-# Copyright (c) Spyder Project Contributors
-# Licensed under the terms of the MIT License
-# (see LICENSE.txt for details)
-
-"""Script to generate requirements/without-spyder.txt"""
-
-import re
-
-with open('requirements/conda.txt') as infile:
-    with open('requirements/without-spyder.txt', 'w') as outfile:
-        for line in infile:
-            package_name = re.match('[-a-z0-9_]*', line).group(0)
-            if package_name != 'spyder':
-                outfile.write(line)
\ No newline at end of file
diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml
new file mode 100644
index 0000000..a329ea8
--- /dev/null
+++ b/.pre-commit-config.yaml
@@ -0,0 +1,13 @@
+repos:
+  - repo: https://github.com/pre-commit/pre-commit-hooks
+    rev: v2.3.0
+    hooks:
+      - id: check-yaml
+      - id: end-of-file-fixer
+      - id: trailing-whitespace
+  - repo: https://github.com/astral-sh/ruff-pre-commit
+    rev: v0.3.4
+    hooks:
+      - id: ruff
+        args: [ --fix ]
+      - id: ruff-format
diff --git a/AUTHORS.txt b/AUTHORS.txt
deleted file mode 100644
index c2c0542..0000000
--- a/AUTHORS.txt
+++ /dev/null
@@ -1,17 +0,0 @@
-The kite-provider project comes from an effort to support external
-completions services inside Spyder. The code in this repository is a a copy of
-original work done over the main spyder repository to support Kite and which
-was the result of Spyder and Kite contributors effort:
-
-* Edgar Andrés Margffoy Tuay <andfoy@gmail.com> (Initial provider implementation)
-* All other developers that contributed to support Kite inside Spyder:
-  <https://github.com/spyder-ide/spyder/commits/4.x/spyder/plugins/completion/kite>
-  <https://github.com/spyder-ide/spyder/commits/5.x/spyder/plugins/completion/providers/kite>
-
-For a full list of PRs over the main spyder repository related with Kite you can check:
- <https://github.com/spyder-ide/spyder/pulls?q=is%3Apr+kite+is%3Aclosed+sort%3Acreated-asc>
-
-For information about the sources and authors of other third-party
-resources used, please see the NOTICE.txt file, located in the
-root of the kite-provider repository or online at:
-<https://github.com/spyder-ide/kite-provider/blob/main/NOTICE.txt>
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
new file mode 100644
index 0000000..6df5a63
--- /dev/null
+++ b/CONTRIBUTING.md
@@ -0,0 +1,152 @@
+# Contributing Guide
+
+langchain-provider is part of the Spyder IDE Github org, and is developed with standard Github flow.
+
+If you're not comfortable with at least the basics of ``git`` and GitHub, we recommend reading beginner tutorials such as [GitHub's Git Guide](https://github.com/git-guides/), its [introduction to basic Git commands](https://guides.github.com/introduction/git-handbook/#basic-git) and its [guide to the fork workflow](https://guides.github.com/activities/forking/), or (if you prefer) their [video equivalents](https://www.youtube.com/githubguides).
+However, this contributing guide should fill you in on most of the basics you need to know.
+
+Let us know if you have any further questions, and we look forward to your contributions!
+
+
+## Reporting Issues
+
+Discover a bug?
+Want a new feature?
+[Open](https://github.com/spyder-ide/langchain-provider/issues/new/choose) an [issue](https://github.com/spyder-ide/langchain-provider/issues)!
+Make sure to describe the bug or feature in detail, with reproducible examples and references if possible, what you are looking to have fixed/added.
+While we can't promise we'll fix everything you might find, we'll certainly take it into consideration, and typically welcome pull requests to resolve accepted issues.
+
+
+
+## Setting Up a Development Environment
+
+**Note**: You may need to substitute ``python3`` for ``python`` in the commands below on some Linux distros where ``python`` isn't mapped to ``python3`` (yet).
+
+### Fork and clone the repo
+
+First, navigate to the [project repository](https://github.com/spyder-ide/langchain-provider) in your web browser and press the ``Fork`` button to make a personal copy of the repository on your own Github account.
+Then, click the ``Clone or Download`` button on your repository, copy the link and run the following on the command line to clone the repo:
+
+```bash
+git clone <LINK-TO-YOUR-REPO>
+```
+
+Finally, set the upstream remote to the official langchain-provider repo with:
+
+```bash
+git remote add upstream https://github.com/spyder-ide/langchain-provider.git
+```
+
+
+### Create and activate a fresh environment
+
+Particularly for development installs, we highly recommend you create and activate a virtual environment to avoid any conflicts with other packages on your system or causing any other issues.
+Of course, you're free to use any environment management tool of your choice (conda, virtualenvwrapper, pyenv, etc).
+
+To do so with Conda (recommended), simply execute the following:
+
+```bash
+conda create -c conda-forge -n langchain-provider-env python=3.9
+```
+
+And activate it with
+
+```bash
+conda activate langchain-provider-env
+```
+
+With pip/venv, you can create a virtual environment with
+
+```bash
+python -m venv langchain-provider-env
+```
+
+And activate it with the following on Linux and macOS,
+
+```bash
+source langchain-provider-env/bin/activate
+```
+
+or on Windows (cmd),
+
+```cmd
+.\langchain-provider-env\Scripts\activate.bat
+```
+
+Regardless of the tool you use, make sure to remember to always activate your environment before using it.
+
+
+### Install langchain-provider in editable mode
+
+Finally, to install the langchain-provider package itself in editable ("development") mode, where updates to the source files will be reflected in the installed package, and include any additional dependencies used for development, run
+
+```bash
+python -m pip install -e .
+```
+
+You can then launch Spyder and use langchain-provider as normal.
+When you make changes in your local copy of the git repository, they will be reflected in your installed copy as soon as you re-run Spyder.
+
+### Pre-commit hooks
+
+We use [pre-commit](https://pre-commit.com/) to run some checks before each commit. To install it in local environment, run:
+
+```bash
+pip install pre-commit
+```
+
+Then, install the pre-commit hooks with:
+
+```bash
+pre-commit install
+```
+
+If you do not want to run the hooks locally the `pre-commit.ci` workflow will run them for you on GitHub.
+
+
+## Making Your Changes
+
+To start working on a new PR, you need to execute these commands, filling in the branch names where appropriate (``<BASE-BRANCH>`` is the branch you're basing your work against, e.g. ``master``, while ``<FEATURE-BRANCH>`` is the branch you'll be creating to store your changes, e.g. ``fix-startup-bug`` or ``add-widget-support``:
+
+```bash
+git checkout <BASE-BRANCH>
+git pull upstream <BASE-BRANCH>
+git checkout -b <FEATURE-BRANCH>
+```
+
+Once you've made and tested your changes, commit them with a descriptive, unique message of 74 characters or less written in the imperative tense, with a capitalized first letter and no period at the end.
+Try to make your commit message understandable on its own, giving the reader a high-level idea of what your changes accomplished without having to dig into the diffs.
+For example:
+
+```bash
+git commit -am "Fix bug reading env variable when importing package on Windows"
+```
+
+If your changes are complex (more than a few dozen lines) and can be broken into discrete steps/parts, its often a good idea to make multiple commits as you work.
+On the other hand, if your changes are fairly small (less than a dozen lines), its usually better to make them as a single commit, and then use the ``git -a --amend`` (followed by ``git push -f``, if you've already pushed your work) if you spot a bug or a reviewer requests a change.
+
+These aren't hard and fast rules, so just use your best judgment, and if there does happen to be a significant issue we'll be happy to help.
+
+
+## Pushing your Changes
+
+Now that your changes are ready to go, you'll need to push them to the appropriate remote.
+All contributors, including core developers, should push to their personal fork and submit a PR from there, to avoid cluttering the upstream repo with feature branches.
+To do so, run:
+
+```bash
+git push -u origin <FEATURE-BRANCH>
+```
+
+Where ``<FEATURE-BRANCH>`` is the name of your feature branch, e.g. ``fix-startup-bug``.
+
+
+
+## Submitting a Pull Request
+
+Finally, create a pull request to the [spyder-ide/langchain-provider repository](https://github.com/spyder-ide/langchain-provider/) on Github.
+Make sure to set the target branch to the one you based your PR off of (``master`` for example).
+
+We'll then review your changes, and after they're ready to go, your work will become an official part of langchain-provider.
+
+Thanks for taking the time to read and follow this guide, and we look forward to your contributions!
diff --git a/LICENSE b/LICENSE
index c4c0e82..3fd1cce 100644
--- a/LICENSE
+++ b/LICENSE
@@ -1,6 +1,6 @@
 MIT License
 
-Copyright (c) 2023 Spyder IDE
+Copyright (c) 2023- Spyder IDE
 
 Permission is hereby granted, free of charge, to any person obtaining a copy
 of this software and associated documentation files (the "Software"), to deal
diff --git a/NOTICE.txt b/NOTICE.txt
index d9960d4..b4e5843 100644
--- a/NOTICE.txt
+++ b/NOTICE.txt
@@ -157,30 +157,30 @@ Files covered:
 ===============================================================================
 
 
-Icons for Kite Completions Provider
+Icons for Langchain Provider
 ---------------------------------
 
 
-Copyright (c) 2019 Kite
+Copyright (c) 2023 Pictogrammers
 
 
-Author: Kite | https://kite.com
-Site: https://kite.com
-Source: https://kite.com
-License: Creative Commons Attribution 4.0 International
-https://creativecommons.org/licenses/by/4.0/
+Author: Austin Andrews | https://pictogrammers.com/contributor/Templarian/
+Site: https://pictogrammers.com
+Source: https://pictogrammers.com/library/mdi/icon/link-variant/
+License: Apache License Version 2.0.
+https://www.apache.org/licenses/LICENSE-2.0.txt
 
 
-Licensed under the terms of the Creative Commons Attribution International 4.0.
+Licensed under the terms of the Apache License Version 2.0.
 
 
-See below for the full text of the Creative Commons Attribution International 4.0 License.
+See below for the full text of the Apache License Version 2.0.
 
 
 Files covered:
 
-kite_provider/images/dark/kite.svg
-kite_provider/images/light/kite.svg
+langchain_provider/images/dark/langchain.svg
+langchain_provider/images/light/langchain.svg
 
 
 -------------------------------------------------------------------------------
@@ -188,6 +188,7 @@ kite_provider/images/light/kite.svg
 
 
 
+
 Full License Text
 =================
 
@@ -2952,4 +2953,4 @@ Apache License 2.0
    distributed under the License is distributed on an "AS IS" BASIS,
    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    See the License for the specific language governing permissions and
-   limitations under the License.
\ No newline at end of file
+   limitations under the License.
diff --git a/README.md b/README.md
index 8bdea9f..cf314d0 100644
--- a/README.md
+++ b/README.md
@@ -7,12 +7,6 @@
 [![OpenCollective Backers](https://opencollective.com/spyder/backers/badge.svg?color=blue)](#backers)
 [![OpenCollective Sponsors](https://opencollective.com/spyder/sponsors/badge.svg?color=blue)](#sponsors)
 
-## Build status
-
-![Linux tests](https://github.com/spyder-ide/langchain-provider/workflows/Linux%20tests/badge.svg)
-![Macos tests](https://github.com/spyder-ide/langchain-provider/workflows/Macos%20tests/badge.svg)
-![Window tests](https://github.com/spyder-ide/langchain-provider/workflows/Windows%20tests/badge.svg)
-
 ----
 
 # Overview
@@ -22,12 +16,25 @@
 
 To use this completions provider you will need to install Spyder 6 (at least 6.0.0a3)
 
-To install the provider package, you can use `pip` with something like:
+To install the provider package from source, you can use `pip` with something like:
 
     pip install git+https://github.com/spyder-ide/langchain-provider.git
 
+Or from PyPI something like:
+
+    pip install langchain-provider
+
+Also, you need to have a OpenAI API key, which you can get from [here](https://platform.openai.com/signup) and then set it as a environment variable (`OPENAI_API_KEY`).
+
+## Preview
+
+![langchain provider demo](https://raw.githubusercontent.com/spyder-ide/langchain-provider/master/langchain-provider.gif)
+
+## Configuration
+
+To configure the provider number of suggestions (1 - 10) or the model to use (`gpt-3.5-turbo`, or `gpt4`) you can click on the Langchain status bar and click the `Change provider parameters` menu entry:
 
-## Common issues
+![langchain provider config](https://raw.githubusercontent.com/spyder-ide/langchain-provider/master/langchain-provider-config.gif)
 
 ## Dependencies
 
@@ -39,7 +46,7 @@ Visit our [CHANGELOG](CHANGELOG.md) file to know more about our new features and
 
 ## Development and contribution
 
-Everyone is welcome to contribute!
+Everyone is welcome to contribute! See our [Contributing guide](CONTRIBUTING.md) for more details.
 
 ## Sponsors
 
diff --git a/RELEASE.md b/RELEASE.md
new file mode 100644
index 0000000..f9c1434
--- /dev/null
+++ b/RELEASE.md
@@ -0,0 +1,106 @@
+# Release Procedure
+
+In the commands below, replace `X.Y.Z` with the release version when needed.
+
+**Note**: We use `pip` instead of `conda` here even on Conda installs, to ensure we always get the latest upstream versions of the build dependencies.
+
+
+## PyPI
+
+To release a new version of QtPy on PyPI:
+
+
+### Prepare
+
+* Close [GitHub milestone](https://github.com/spyder-ide/langchain-provider/milestones) and ensure all issues are resolved/moved
+
+* Update local repo
+
+  ```bash
+  git restore . && git switch master && git pull upstream master
+  ```
+
+* Clean local repo
+
+  ```bash
+  git clean -xfdi
+  ```
+
+
+### Commit
+
+* Install/upgrade Loghub
+
+  ```bash
+  pip install --upgrade loghub
+  ```
+
+* Update `CHANGELOG.md` using Loghub to generate the list of issues and PRs merged to add at the top of the file
+
+  ```bash
+  loghub -m vX.Y.Z spyder-ide/langchain-provider
+  ```
+
+* Update `version` in `pyproject.toml` (set release version, remove `.dev0`)
+
+* Create release commit
+
+  ```bash
+  git commit -am "Release X.Y.Z"
+  ```
+
+
+### Build
+
+* Update the packaging stack
+
+  ```bash
+  python -m pip install --upgrade pip
+  pip install --upgrade --upgrade-strategy eager build setuptools twine wheel
+  ```
+
+* Build source distribution and wheel
+
+  ```bash
+  python -bb -X dev -W error -m build
+  ```
+
+* Check distribution archives
+
+  ```bash
+  twine check --strict dist/*
+  ```
+
+
+### Release
+
+* Upload distribution packages to PyPI
+
+  ```bash
+  twine upload dist/*
+  ```
+
+* Create release tag
+
+  ```bash
+  git tag -a vX.Y.Z -m "Release X.Y.Z"
+  ```
+
+
+### Finalize
+
+* Update `version` in `pyproject.toml` (add `.dev0` and increment minor)
+
+* Create `Back to work` commit
+
+  ```bash
+  git commit -am "Back to work"
+  ```
+
+* Push new release commits and tags to `master`
+
+  ```bash
+  git push upstream master --follow-tags
+  ```
+
+* Create a [GitHub release](https://github.com/spyder-ide/langchain-provider/releases) from the tag
diff --git a/langchain-provider-config.gif b/langchain-provider-config.gif
new file mode 100644
index 0000000..2466c66
Binary files /dev/null and b/langchain-provider-config.gif differ
diff --git a/langchain-provider.gif b/langchain-provider.gif
new file mode 100644
index 0000000..076a0c2
Binary files /dev/null and b/langchain-provider.gif differ
diff --git a/langchain_provider/__init__.py b/langchain_provider/__init__.py
index e1f3ecc..1a88c8e 100644
--- a/langchain_provider/__init__.py
+++ b/langchain_provider/__init__.py
@@ -3,4 +3,4 @@
 # Copyright © Spyder Project Contributors
 # Licensed under the terms of the MIT License
 
-"""Langchain client requests and constants."""
\ No newline at end of file
+"""Langchain client requests and constants."""
diff --git a/langchain_provider/client.py b/langchain_provider/client.py
index e3fb567..581e448 100644
--- a/langchain_provider/client.py
+++ b/langchain_provider/client.py
@@ -3,47 +3,43 @@
 # Copyright © Spyder Project Contributors
 # Licensed under the terms of the MIT License
 
-"""Kite completions HTTP client."""
+"""Langchain completions HTTP client."""
 
 # Standard library imports
+import json
 import logging
-import os
 
 # Third party imports
-from langchain.chat_models import ChatOpenAI
+from langchain_community.chat_models import ChatOpenAI
 from langchain.chains import LLMChain
 from langchain.prompts.chat import (
-            ChatPromptTemplate,
-            SystemMessagePromptTemplate,
-            HumanMessagePromptTemplate,
-        )
+    ChatPromptTemplate,
+    SystemMessagePromptTemplate,
+    HumanMessagePromptTemplate,
+)
 from qtpy.QtCore import QObject, QThread, Signal, QMutex, Slot
-import json
-from collections import defaultdict
 
 # Spyder imports
-from spyder.config.base import _, running_under_pytest
-from spyder.py3compat import TEXT_TYPES
-from spyder.plugins.completion.api import (
-    CompletionRequestTypes, CompletionItemKind)
+from spyder.plugins.completion.api import CompletionRequestTypes, CompletionItemKind
 
 
 logger = logging.getLogger(__name__)
 
 
-LANG_COMPLETION = 'Langchain'
-LANG_ICON_SCALE = (416.14 / 526.8)
+LANG_COMPLETION = "Langchain"
+LANG_ICON_SCALE = 1
+
 
 class LangchainClient(QObject):
     sig_response_ready = Signal(int, dict)
     sig_client_started = Signal()
-    sig_client_eror = Signal()
+    sig_client_error = Signal(str)
     sig_perform_request = Signal(dict)
     sig_perform_status_request = Signal(str)
     sig_status_response_ready = Signal((str,), (dict,))
     sig_onboarding_response_ready = Signal(str)
 
-    def __init__(self, parent, template, model_name,enable_code_snippets=True,language='python'):
+    def __init__(self, parent, template, model_name, language="python"):
         QObject.__init__(self, parent)
         self.requests = {}
         self.language = language
@@ -51,49 +47,62 @@ def __init__(self, parent, template, model_name,enable_code_snippets=True,langua
         self.opened_files = {}
         self.opened_files_status = {}
         self.thread_started = False
-        self.enable_code_snippets = enable_code_snippets
         self.thread = QThread(None)
         self.moveToThread(self.thread)
         self.thread.started.connect(self.started)
         self.sig_perform_request.connect(self.handle_msg)
         self.sig_perform_status_request.connect(self.get_status)
 
-        self.template=template
-        self.model_name=model_name
-        self.chain=None
+        self.template = template
+        self.model_name = model_name
+        self.chain = None
 
     def start(self):
         if not self.thread_started:
             self.thread.start()
-        logger.debug('Starting LangChain session...')
+        logger.debug("Starting LangChain session...")
         system_message_prompt = SystemMessagePromptTemplate.from_template(self.template)
         code_template = "{text}"
         code_message_prompt = HumanMessagePromptTemplate.from_template(
             code_template,
+        )
+        try:
+            llm = ChatOpenAI(
+                temperature=0,
+                model_name=self.model_name,
+            )
+            chat_prompt = ChatPromptTemplate.from_messages(
+                [system_message_prompt, code_message_prompt]
             )
-        try:        
-            llm=ChatOpenAI(temperature=0,model_name=self.model_name,openai_api_key=os.environ.get("OPENAI_API_KEY"))
-            chat_prompt = ChatPromptTemplate.from_messages([system_message_prompt, code_message_prompt])
             chain = LLMChain(
                 llm=llm,
                 prompt=chat_prompt,
-                )
-            self.chain=chain
+            )
+            self.chain = chain
             self.sig_client_started.emit()
-        except:
-            self.sig_client_error.emit()
-        
+        except ValueError as e:
+            logger.debug(e)
+            self.sig_client_error.emit("Missing OpenAI API key")
+        except Exception as e:
+            logger.debug(e)
+            self.sig_client_error.emit("Unexpected error")
 
     def started(self):
         self.thread_started = True
 
     def stop(self):
         if self.thread_started:
-            logger.debug('Closing LangChain session...')
+            logger.debug("Closing LangChain session...")
             self.thread.quit()
             self.thread.wait()
             self.thread_started = False
 
+    def update_configuration(self, model_name, template):
+        self.stop()
+        self.model_name = model_name
+        self.template = template
+        self.start()
+
     def get_status(self, filename):
         """Get langchain status for a given filename."""
         langchain_status = None
@@ -104,15 +113,15 @@ def get_status(self, filename):
     def run_chain(self, params=None):
         response = None
         try:
-            prevResponse = self.chain.invoke(params)['text']
-            if(prevResponse[0] == '"'):
-                response=json.loads("{"+prevResponse+"}")
+            prevResponse = self.chain.invoke(params)["text"]
+            if prevResponse[0] == '"':
+                response = json.loads("{" + prevResponse + "}")
             else:
-                response=json.loads(prevResponse)
+                response = json.loads(prevResponse)
             return response
-        except:
-            self.sig_client_error.emit()
-            return None
+        except Exception:
+            self.sig_client_error.emit("No suggestions available")
+            return {"suggestions": []}
 
     def send(self, params):
         response = None
@@ -122,32 +131,31 @@ def send(self, params):
     @Slot(dict)
     def handle_msg(self, message):
         """Handle one message"""
-        msg_type, _id, file, msg = [
-            message[k] for k in ('type', 'id', 'file', 'msg')]
-        logger.debug(u'Perform request {0} with id {1}'.format(msg_type, _id))
+        msg_type, _id, file, msg = [message[k] for k in ("type", "id", "file", "msg")]
+        logger.debug("Perform request {0} with id {1}".format(msg_type, _id))
         if msg_type == CompletionRequestTypes.DOCUMENT_DID_OPEN:
-            self.opened_files[msg['file']] = msg['text']
+            self.opened_files[msg["file"]] = msg["text"]
         elif msg_type == CompletionRequestTypes.DOCUMENT_DID_CHANGE:
-            self.opened_files[msg['file']] = msg['text']            
+            self.opened_files[msg["file"]] = msg["text"]
         elif msg_type == CompletionRequestTypes.DOCUMENT_COMPLETION:
-            response=self.send(self.opened_files[msg['file']])
+            response = self.send(self.opened_files[msg["file"]])
             logger.debug(response)
             if response is None:
-                return {'params': []}
+                return {"params": []}
             spyder_completions = []
-            completions = response['suggestions']
+            completions = response["suggestions"]
             if completions is not None:
                 for i, completion in enumerate(completions):
                     entry = {
-                        'kind': CompletionItemKind.TEXT,
-                        'label': completion,
-                        'insertText': completion,
-                        'filterText': '',
+                        "kind": CompletionItemKind.TEXT,
+                        "label": completion,
+                        "insertText": completion,
+                        "filterText": "",
                         # Use the returned ordering
-                        'sortText': (0, i),
-                        'documentation': completion,
-                        'provider': LANG_COMPLETION,
-                        #'icon': ('kite', LANG_ICON_SCALE)
+                        "sortText": (0, i),
+                        "documentation": completion,
+                        "provider": LANG_COMPLETION,
+                        "icon": ("langchain", LANG_ICON_SCALE),
                     }
                     spyder_completions.append(entry)
-            self.sig_response_ready.emit(_id, {'params': spyder_completions})
\ No newline at end of file
+            self.sig_response_ready.emit(_id, {"params": spyder_completions})
diff --git a/langchain_provider/images/dark/kite.svg b/langchain_provider/images/dark/kite.svg
deleted file mode 100644
index e908b4a..0000000
--- a/langchain_provider/images/dark/kite.svg
+++ /dev/null
@@ -1,1 +0,0 @@
-<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="none"><path fill="#FAFAFA" d="m10.275 15 1.543-5.998-4.054-2.079-2.153 4.073L10.275 15Z"/><path fill="#FAFAFA" d="M4.704 10.217 7.333 5.55l4.784 2.292L13 4.409 5.884 1 2 7.896l2.704 2.321Z"/></svg>
\ No newline at end of file
diff --git a/langchain_provider/images/dark/langchain.svg b/langchain_provider/images/dark/langchain.svg
new file mode 100644
index 0000000..b08f5e4
--- /dev/null
+++ b/langchain_provider/images/dark/langchain.svg
@@ -0,0 +1,1 @@
+<svg xmlns="http://www.w3.org/2000/svg" width="16px" height="16px" viewBox="0 0 24 24"><path fill="white" d="M10.59 13.41c.41.39.41 1.03 0 1.42c-.39.39-1.03.39-1.42 0a5.003 5.003 0 0 1 0-7.07l3.54-3.54a5.003 5.003 0 0 1 7.07 0a5.003 5.003 0 0 1 0 7.07l-1.49 1.49c.01-.82-.12-1.64-.4-2.42l.47-.48a2.982 2.982 0 0 0 0-4.24a2.982 2.982 0 0 0-4.24 0l-3.53 3.53a2.982 2.982 0 0 0 0 4.24m2.82-4.24c.39-.39 1.03-.39 1.42 0a5.003 5.003 0 0 1 0 7.07l-3.54 3.54a5.003 5.003 0 0 1-7.07 0a5.003 5.003 0 0 1 0-7.07l1.49-1.49c-.01.82.12 1.64.4 2.43l-.47.47a2.982 2.982 0 0 0 0 4.24a2.982 2.982 0 0 0 4.24 0l3.53-3.53a2.982 2.982 0 0 0 0-4.24a.973.973 0 0 1 0-1.42"/></svg>
diff --git a/langchain_provider/images/light/kite.svg b/langchain_provider/images/light/kite.svg
deleted file mode 100644
index 65a0530..0000000
--- a/langchain_provider/images/light/kite.svg
+++ /dev/null
@@ -1,1 +0,0 @@
-<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="none"><path fill="#37414F" d="m10.275 15 1.543-5.998-4.054-2.079-2.153 4.073L10.275 15Z"/><path fill="#37414F" d="M4.704 10.217 7.333 5.55l4.784 2.292L13 4.409 5.884 1 2 7.896l2.704 2.321Z"/></svg>
\ No newline at end of file
diff --git a/langchain_provider/images/light/langchain.svg b/langchain_provider/images/light/langchain.svg
new file mode 100644
index 0000000..b3e9ac8
--- /dev/null
+++ b/langchain_provider/images/light/langchain.svg
@@ -0,0 +1,1 @@
+<svg xmlns="http://www.w3.org/2000/svg" width="16px" height="16px" viewBox="0 0 24 24"><path fill="black" d="M10.59 13.41c.41.39.41 1.03 0 1.42c-.39.39-1.03.39-1.42 0a5.003 5.003 0 0 1 0-7.07l3.54-3.54a5.003 5.003 0 0 1 7.07 0a5.003 5.003 0 0 1 0 7.07l-1.49 1.49c.01-.82-.12-1.64-.4-2.42l.47-.48a2.982 2.982 0 0 0 0-4.24a2.982 2.982 0 0 0-4.24 0l-3.53 3.53a2.982 2.982 0 0 0 0 4.24m2.82-4.24c.39-.39 1.03-.39 1.42 0a5.003 5.003 0 0 1 0 7.07l-3.54 3.54a5.003 5.003 0 0 1-7.07 0a5.003 5.003 0 0 1 0-7.07l1.49-1.49c-.01.82.12 1.64.4 2.43l-.47.47a2.982 2.982 0 0 0 0 4.24a2.982 2.982 0 0 0 4.24 0l3.53-3.53a2.982 2.982 0 0 0 0-4.24a.973.973 0 0 1 0-1.42"/></svg>
diff --git a/langchain_provider/parsing/__init__.py b/langchain_provider/parsing/__init__.py
deleted file mode 100644
index 5a8051b..0000000
--- a/langchain_provider/parsing/__init__.py
+++ /dev/null
@@ -1,54 +0,0 @@
-# -*- coding: utf-8 -*-
-
-# Copyright © Spyder Project Contributors
-# Licensed under the terms of the MIT License
-
-# Standard library imports
-import re
-
-
-ident_re = r'[a-zA-Z_][a-zA-Z0-9_]*'
-dotted_path_re = r'{ident}(?:\.{ident})*'.format(ident=ident_re)
-ident_full_re = ident_re+r'\Z'
-
-
-def find_returning_function_path(text, cursor, line_start='\n'):
-    """
-    :param text: Python source to analyze
-    :param cursor: The starting cursor in the source
-    :param line_start: line_start used in the source
-    :return: a string representing the definition value or None
-
-    Finds the (syntactic) path of the function that
-    returned the value of the name before the cursor.
-
-    For example, the following input yields "bar.baz":
-      foo = bar.baz("abc")
-      foo.ca‸r
-    """
-
-    # Find the previous space to get the expression before the cursor
-    for i, c in enumerate(reversed(text[:cursor])):
-        if c == '.' or c == '_' or c.isalnum():
-            continue
-        break
-    else:
-        return None
-    expr = text[cursor-i:cursor]
-
-    # Take the first part of the expression, and check that it's a name
-    name = expr.split('.', 1)[0]
-    if not re.match(ident_full_re, name):
-        return None
-
-    assign_re = r'{line_start}\s*{name}\s*=\s*({dotted_path})\('.format(
-        line_start=re.escape(line_start),
-        name=re.escape(name),
-        dotted_path=dotted_path_re)
-    match = None
-    for match in re.finditer(assign_re, text[:cursor]):
-        pass
-    if match is None:
-        return None
-
-    return match.group(1)
diff --git a/langchain_provider/provider.py b/langchain_provider/provider.py
index 0b1c8e2..396fd1d 100644
--- a/langchain_provider/provider.py
+++ b/langchain_provider/provider.py
@@ -3,40 +3,39 @@
 # Copyright © Spyder Project Contributors
 # Licensed under the terms of the MIT License
 
-"""Kite completion HTTP client."""
+"""Langchain completion HTTP client."""
 
 # Standard library imports
 import logging
-import functools
 import os
-import os.path as osp
 
 # Qt imports
 from qtpy.QtCore import Slot
-from qtpy.QtWidgets import QMessageBox
 
 # Local imports
 from langchain_provider.client import LangchainClient
-from langchain_provider.widgets import (LangchainStatusWidget)
+from langchain_provider.widgets import LangchainStatusWidget
 
 # Spyder imports
 from spyder.api.config.decorators import on_conf_change
-from spyder.config.base import _, running_under_pytest, get_module_data_path
+from spyder.config.base import running_under_pytest, get_module_data_path
 from spyder.plugins.completion.api import SpyderCompletionProvider
 from spyder.utils.image_path_manager import IMAGE_PATH_MANAGER
-from spyder.utils.programs import run_program
 
 
 logger = logging.getLogger(__name__)
 
 
 class LangchainProvider(SpyderCompletionProvider):
-    COMPLETION_PROVIDER_NAME = 'langchain'
+    COMPLETION_PROVIDER_NAME = "langchain"
     DEFAULT_ORDER = 1
     SLOW = True
     CONF_VERSION = "1.0.0"
-    SUGGESTIONS='4'
-    LANGUAGE='Python'
+    CONF_DEFAULTS = [
+        ("suggestions", 4),
+        ("language", "Python"),
+        ("model_name", "gpt-3.5-turbo"),
+    ]
     TEMPLATE_PARAM = """You are a helpful assistant in completing following {0} code based
                   on the previous sentence.
                   You always complete the code in same line and give {1} suggestions.
@@ -44,51 +43,47 @@ class LangchainProvider(SpyderCompletionProvider):
                   AI : "suggestions": ["print(a)", "print(b)", "print(a+b)"]
                   Example : a=3 b=4 c
                   AI : "suggestions": ["c=a+b", "c=a-b", "c=5"]
-                  Format the output as JSON with the following key:                  
+                  Format the output as JSON with the following key:
                       suggestions
-                  """.format(LANGUAGE,SUGGESTIONS)
-    MODEL_NAME_PARAM = "gpt-3.5-turbo"
+                  """
 
     def __init__(self, parent, config):
         super().__init__(parent, config)
         IMAGE_PATH_MANAGER.add_image_path(
-            get_module_data_path('langchain_provider', relpath='images')
+            get_module_data_path("langchain_provider", relpath="images")
         )
         self.available_languages = []
-        self.client = LangchainClient(None,model_name=self.MODEL_NAME_PARAM,template=self.TEMPLATE_PARAM)
+        self.client = LangchainClient(
+            None,
+            model_name=self.get_conf("model_name"),
+            template=self.TEMPLATE_PARAM.format(
+                self.get_conf("language"), self.get_conf("suggestions")
+            ),
+        )
 
         # Signals
         self.client.sig_client_started.connect(
-            lambda: self.sig_provider_ready.emit(
-                self.COMPLETION_PROVIDER_NAME))
+            lambda: self.sig_provider_ready.emit(self.COMPLETION_PROVIDER_NAME)
+        )
         self.client.sig_client_error.connect(self.set_status_error)
-        self.client.sig_status_response_ready[str].connect(
-            self.set_status)
-        self.client.sig_status_response_ready[dict].connect(
-            self.set_status)
+        self.client.sig_status_response_ready[str].connect(self.set_status)
+        self.client.sig_status_response_ready[dict].connect(self.set_status)
         self.client.sig_response_ready.connect(
             lambda _id, resp: self.sig_response_ready.emit(
-                self.COMPLETION_PROVIDER_NAME, _id, resp))
+                self.COMPLETION_PROVIDER_NAME, _id, resp
+            )
+        )
 
         # Status bar widget
-        self.STATUS_BAR_CLASSES = [
-            self.create_statusbar
-        ]
+        self.STATUS_BAR_CLASSES = [self.create_statusbar]
         self.started = False
-        # Config
-        self.update_langchain_configuration(self.config)
 
     # ------------------ SpyderCompletionProvider methods ---------------------
     def get_name(self):
-        return 'LangChain'
+        return "LangChain"
 
     def send_request(self, language, req_type, req, req_id):
-        request = {
-            'type': req_type,
-            'file': req['file'],
-            'id': req_id,
-            'msg': req
-        }
+        request = {"type": req_type, "file": req["file"], "id": req_id, "msg": req}
         self.client.sig_perform_request.emit(request)
 
     def start_completion_services_for_language(self, language):
@@ -109,37 +104,34 @@ def shutdown(self):
     def set_status(self, status):
         """Show Langchain status for the current file."""
         self.sig_call_statusbar.emit(
-            LangchainStatusWidget.ID, 'set_value', (status,), {})
-        
-    def set_status_error(self):
+            LangchainStatusWidget.ID, "set_value", (status,), {}
+        )
+
+    def set_status_error(self, error_message):
         """Show Langchain status for the current file."""
         self.sig_call_statusbar.emit(
-            LangchainStatusWidget.ID, 'set_value', ("Unexpected error",), {})    
+            LangchainStatusWidget.ID, "set_value", (error_message,), {}
+        )
 
     def file_opened_closed_or_updated(self, filename, _language):
         """Request status for the given file."""
         self.client.sig_perform_status_request.emit(filename)
 
-    @on_conf_change(
-        section='completions', option=('enabled_providers', 'langchain'))
+    @on_conf_change(section="completions", option=("enabled_providers", "langchain"))
     def on_langchain_enable_changed(self, value):
-        self.sig_call_statusbar.emit(
-            LangchainStatusWidget.ID, 'set_value', (None,), {})
-
-    @on_conf_change(section='completions', option='enable_code_snippets')
-    def on_code_snippets_changed(self, value):
-        if running_under_pytest():
-            if not os.environ.get('SPY_TEST_USE_INTROSPECTION'):
-                return
-
-        self.client.enable_code_snippets = self.get_conf(
-            'enable_code_snippets', section='completions')
+        self.sig_call_statusbar.emit(LangchainStatusWidget.ID, "set_value", (None,), {})
 
     @on_conf_change
     def update_langchain_configuration(self, config):
         if running_under_pytest():
-            if not os.environ.get('SPY_TEST_USE_INTROSPECTION'):
+            if not os.environ.get("SPY_TEST_USE_INTROSPECTION"):
                 return
+        self.client.update_configuration(
+            self.get_conf("model_name"),
+            self.TEMPLATE_PARAM.format(
+                self.get_conf("language"), self.get_conf("suggestions")
+            ),
+        )
 
     def create_statusbar(self, parent):
         return LangchainStatusWidget(parent, self)
diff --git a/langchain_provider/widgets/__init__.py b/langchain_provider/widgets/__init__.py
index 5187450..306c9bd 100644
--- a/langchain_provider/widgets/__init__.py
+++ b/langchain_provider/widgets/__init__.py
@@ -3,6 +3,10 @@
 # Copyright © Spyder Project Contributors
 # Licensed under the terms of the MIT License
 
-"""Kite related widgets."""
+"""Langchain related widgets."""
 
 from .status import LangchainStatusWidget
+
+__all__ = [
+    "LangchainStatusWidget",
+]
diff --git a/langchain_provider/widgets/config_dialog.py b/langchain_provider/widgets/config_dialog.py
new file mode 100644
index 0000000..3bc462e
--- /dev/null
+++ b/langchain_provider/widgets/config_dialog.py
@@ -0,0 +1,75 @@
+# -*- coding: utf-8 -*-
+#
+# Copyright © Spyder Project Contributors
+# Licensed under the terms of the MIT License
+
+"""
+Dialog widget for Langchain + OpenAI completions configs.
+"""
+
+# Standard library imports
+import logging
+
+# Third party imports
+from qtpy.QtCore import Qt
+from qtpy.QtWidgets import (
+    QComboBox,
+    QDialog,
+    QDialogButtonBox,
+    QFormLayout,
+    QSpinBox,
+    QHBoxLayout,
+    QVBoxLayout,
+)
+
+# Spyder imports
+from spyder.api.translations import _
+
+logger = logging.getLogger(__name__)
+
+
+class LangchainConfigDialog(QDialog):
+    def __init__(self, provider, parent=None):
+        super().__init__(parent=parent)
+
+        self._provider = provider
+
+        self.setAttribute(Qt.WA_DeleteOnClose)
+        self.setWindowTitle(_("Langchain provider configuration"))
+        self.setModal(True)
+
+        suggestions_label_text = _("Suggestions number:")
+        self.suggestions_spinbox = QSpinBox()
+        self.suggestions_spinbox.setRange(1, 10)
+        self.suggestions_spinbox.setSingleStep(1)
+        self.suggestions_spinbox.setValue(provider.get_conf("suggestions"))
+
+        model_label_text = _("Model name:")
+        self.model_combobox = QComboBox()
+        self.model_combobox.addItems(["gpt-3.5-turbo", "gpt-4"])
+        self.model_combobox.setCurrentText(provider.get_conf("model_name"))
+
+        form_layout = QFormLayout()
+        form_layout.addRow(suggestions_label_text, self.suggestions_spinbox)
+        form_layout.addRow(model_label_text, self.model_combobox)
+
+        bbox = QDialogButtonBox(
+            QDialogButtonBox.Ok | QDialogButtonBox.Cancel, Qt.Vertical, self
+        )
+        bbox.accepted.connect(self.accept)
+        bbox.rejected.connect(self.reject)
+        btn_layout = QVBoxLayout()
+        btn_layout.addWidget(bbox)
+        btn_layout.addStretch(1)
+
+        layout = QHBoxLayout()
+        layout.addLayout(form_layout)
+        layout.addLayout(btn_layout)
+        self.setLayout(layout)
+
+        self.suggestions_spinbox.setFocus()
+
+    def accept(self):
+        self._provider.set_conf("suggestions", self.suggestions_spinbox.value())
+        self._provider.set_conf("model_name", self.model_combobox.currentText())
+        super().accept()
diff --git a/langchain_provider/widgets/status.py b/langchain_provider/widgets/status.py
index 2c3d2fc..c65b23a 100644
--- a/langchain_provider/widgets/status.py
+++ b/langchain_provider/widgets/status.py
@@ -4,7 +4,7 @@
 # Licensed under the terms of the MIT License
 
 """
-Status widget for Kite completions.
+Status widget for Langchain + OpenAI completions.
 """
 
 # Standard library imports
@@ -12,25 +12,27 @@
 import os
 
 # Third party imports
-from qtpy.QtCore import QPoint, Signal
+from qtpy.QtCore import QPoint
 
 # Spyder imports
+from spyder.api.translations import _
 from spyder.api.widgets.status import StatusBarWidget
-from spyder.config.base import _
 from spyder.utils.icon_manager import ima
 from spyder.api.widgets.menus import SpyderMenu
 from spyder.utils.qthelpers import add_actions, create_action
 
 # Local imports
+from .config_dialog import LangchainConfigDialog
 
 logger = logging.getLogger(__name__)
 
 
 class LangchainStatusWidget(StatusBarWidget):
     """Status bar widget for LangChain completions status."""
+
     BASE_TOOLTIP = _("LangChain completions status")
-    DEFAULT_STATUS = _('not reachable')
-    ID = 'langchain_status'
+    DEFAULT_STATUS = _("not reachable")
+    ID = "langchain_status"
 
     def __init__(self, parent, provider):
         self.provider = provider
@@ -42,15 +44,15 @@ def __init__(self, parent, provider):
 
     def set_value(self, value):
         """Return Langchain completions state."""
-        langchain_enabled = self.provider.get_conf(('enabled_providers', 'langchain'),
-                                              default=True,
-                                              section='completions')
+        langchain_enabled = self.provider.get_conf(
+            ("enabled_providers", "langchain"), default=True, section="completions"
+        )
 
-        if (value is not None and 'short' in value):
-            self.tooltip = value['long']
-            value = value['short']
+        if value is not None and "short" in value:
+            self.tooltip = value["long"]
+            value = value["short"]
         elif value is not None:
-            self.setVisible(True)            
+            self.setVisible(True)
         elif value is None:
             value = self.DEFAULT_STATUS
             self.tooltip = self.BASE_TOOLTIP
@@ -63,22 +65,25 @@ def get_tooltip(self):
         """Reimplementation to get a dynamic tooltip."""
         return self.tooltip
 
+    def open_provider_preferences(self):
+        config_dialog = LangchainConfigDialog(self.provider, parent=self)
+        config_dialog.show()
+
     def show_menu(self):
         """Display a menu when clicking on the widget."""
         menu = self.menu
         menu.clear()
-        text = _("Change default parameters to autocompletions")
+        text = _("Change provider parameters")
         change_action = create_action(
             self,
             text=text,
-            #triggered=self.open_interpreter_preferences,
+            triggered=self.open_provider_preferences,
         )
         add_actions(menu, [change_action])
         rect = self.contentsRect()
-        os_height = 7 if os.name == 'nt' else 12
-        pos = self.mapToGlobal(
-            rect.topLeft() + QPoint(-40, -rect.height() - os_height))
-        menu.popup(pos)    
+        os_height = 7 if os.name == "nt" else 12
+        pos = self.mapToGlobal(rect.topLeft() + QPoint(-40, -rect.height() - os_height))
+        menu.popup(pos)
 
     def get_icon(self):
-        return ima.icon('kite')
+        return ima.icon("langchain")
diff --git a/pyproject.toml b/pyproject.toml
index 471dcc1..8737700 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -4,17 +4,17 @@ build-backend = "setuptools.build_meta"
 
 [project]
 name = "langchain-provider"
-version = "0.2.0"
+version = "0.1.0.dev0"
 description = "Langchain provider for Spyder"
 authors = [
     {name = "Spyder Project Contributors", email = "spyder.python@gmail.com"},
 ]
 license = {text = "MIT license"}
-dependencies = ["psutil", "qtawesome", "qtpy", "spyder>=6.0.0a3"]
+dependencies = ["langchain", "langchain-community", "openai", "qtawesome", "qtpy", "spyder>=6.0.0a3"]
 requires-python = ">= 3.8"
 readme = "README.md"
 classifiers = [
-    "Development Status :: 7 - Inactive",
+    "Development Status :: 3 - Alpha",
     "Intended Audience :: Developers",
     "Intended Audience :: Education",
     "Intended Audience :: Science/Research",
@@ -27,14 +27,11 @@ classifiers = [
     "Topic :: Text Editors :: Integrated Development Environments (IDE)",
 ]
 
+[project.optional-dependencies]
+extras = ["pre-commit"]
+
 [project.urls]
-Homepage = "https://github.com/jsbautista/spyder-completion-provider"
+Homepage = "https://github.com/spyder-ide/langchain-provider"
 
 [project.entry-points."spyder.completions"]
 langchain = "langchain_provider.provider:LangchainProvider"
-
-#[tool.setuptools]
-#packages = ["langchain_provider"]
-#py-modules = ["__init__"]
-#license-files = ["LICENSE"]
-#include-package-data = false
diff --git a/requirements/conda.txt b/requirements/conda.txt
deleted file mode 100644
index e5a9d38..0000000
--- a/requirements/conda.txt
+++ /dev/null
@@ -1,6 +0,0 @@
-langchain
-psutil
-qtawesome
-qtpy
-setuptools
-spyder>=6.0
\ No newline at end of file


Test patch:
diff --git a/.github/workflows/linux-tests.yml b/.github/workflows/linux-tests.yml
deleted file mode 100644
index 4a60426..0000000
--- a/.github/workflows/linux-tests.yml
+++ /dev/null
@@ -1,80 +0,0 @@
-name: Linux tests
-
-on:
-  push:
-    branches:
-    - main
-  pull_request:
-    branches:
-    - main
-
-jobs:
-  linux:
-    name: Linux Py${{ matrix.PYTHON_VERSION }} spyder-from-${{ matrix.SPYDER_SOURCE }}
-    runs-on: ubuntu-latest
-    env:
-      CI: True
-      PYTHON_VERSION: ${{ matrix.PYTHON_VERSION }}
-      RUNNER_OS: 'ubuntu'
-    strategy:
-      fail-fast: false 
-      matrix:
-        PYTHON_VERSION: ['3.10']
-        SPYDER_SOURCE: ['git']
-    steps:
-      - name: Checkout branch
-        uses: actions/checkout@v2
-      - name: Install System Packages
-        run: | 
-          sudo apt-get update
-          sudo apt-get install libegl1-mesa
-      - name: Install Conda
-        uses: conda-incubator/setup-miniconda@v2
-        with:
-           activate-environment: test
-           auto-update-conda: false
-           auto-activate-base: false
-           python-version: ${{ matrix.PYTHON_VERSION }}
-           channels: conda-forge/label/spyder_kernels_rc,conda-forge,defaults
-           channel-priority: strict
-           miniforge-variant: Mambaforge
-      - name: Checkout Spyder from git
-        if: matrix.SPYDER_SOURCE == 'git'
-        uses: actions/checkout@v3
-        with:
-          repository: 'spyder-ide/spyder'
-          path: 'spyder'
-      - name: Install Spyder's dependencies (main)
-        if: matrix.SPYDER_SOURCE == 'git'
-        shell: bash -l {0}
-        run: conda env update --file spyder/requirements/main.yml
-      - name: Install Spyder from source
-        if: matrix.SPYDER_SOURCE == 'git'
-        shell: bash -l {0}
-        run: pip install -e spyder
-      - name: Install package dependencies (without Spyder)
-        if: matrix.SPYDER_SOURCE == 'git'
-        shell: bash -l {0}
-        run: |
-          python .github/scripts/generate-without-spyder.py
-          conda install --file requirements/without-spyder.txt -y
-      - name: Install package dependencies
-        if: matrix.SPYDER_SOURCE == 'conda'
-        shell: bash -l {0}
-        run: conda install --file requirements/conda.txt -y -q -c conda-forge
-      - name: Install test dependencies
-        shell: bash -l {0}
-        run: |
-          conda install nomkl -y -q
-          conda install -c spyder-ide --file requirements/tests.txt -y -q
-      - name: Install Package
-        shell: bash -l {0}
-        run: pip install --no-deps -e .
-      - name: Show environment information
-        shell: bash -l {0}
-        run: |
-          conda info
-          conda list
-      - name: Run tests
-        shell: bash -l {0}
-        run: pytest completion_provider -vv
diff --git a/.github/workflows/macos-tests.yml b/.github/workflows/macos-tests.yml
deleted file mode 100644
index 466049a..0000000
--- a/.github/workflows/macos-tests.yml
+++ /dev/null
@@ -1,76 +0,0 @@
-name: Macos tests
-
-on:
-  push:
-    branches:
-    - main
-  pull_request:
-    branches:
-    - main
-
-jobs:
-  macos:
-    name: Mac Py${{ matrix.PYTHON_VERSION }} spyder-from-${{ matrix.SPYDER_SOURCE }}
-    runs-on: macos-latest
-    env:
-      CI: True
-      PYTHON_VERSION: ${{ matrix.PYTHON_VERSION }}
-      RUNNER_OS: 'macos'
-    strategy:
-      fail-fast: false 
-      matrix:
-        PYTHON_VERSION: ['3.10']
-        SPYDER_SOURCE: ['git']
-    steps:
-      - name: Checkout branch
-        uses: actions/checkout@v2
-      - name: Install Conda
-        uses: conda-incubator/setup-miniconda@v2
-        with:
-           activate-environment: test
-           auto-update-conda: false
-           auto-activate-base: false
-           python-version: ${{ matrix.PYTHON_VERSION }}
-           channels: conda-forge/label/spyder_kernels_rc,conda-forge,defaults
-           channel-priority: strict
-           miniforge-variant: Mambaforge
-      - name: Checkout Spyder from git
-        if: matrix.SPYDER_SOURCE == 'git'
-        uses: actions/checkout@v3
-        with:
-          repository: 'spyder-ide/spyder'
-          path: 'spyder'
-      - name: Install Spyder's dependencies (main)
-        if: matrix.SPYDER_SOURCE == 'git'
-        shell: bash -l {0}
-        run: conda env update --file spyder/requirements/main.yml
-      - name: Install Spyder from source
-        if: matrix.SPYDER_SOURCE == 'git'
-        shell: bash -l {0}
-        run: pip install -e spyder
-      - name: Install package dependencies (without Spyder)
-        if: matrix.SPYDER_SOURCE == 'git'
-        shell: bash -l {0}
-        run: |
-          python .github/scripts/generate-without-spyder.py
-          conda install --file requirements/without-spyder.txt -y
-      - name: Install package dependencies
-        if: matrix.SPYDER_SOURCE == 'conda'
-        shell: bash -l {0}
-        run: conda install --file requirements/conda.txt -y -q -c conda-forge
-      - name: Install test dependencies
-        shell: bash -l {0}
-        run: |
-          conda install nomkl -y -q
-          conda install -c spyder-ide --file requirements/tests.txt -y -q
-      - name: Install Package
-        shell: bash -l {0}
-        run: pip install --no-deps -e .
-      - name: Show environment information
-        shell: bash -l {0}
-        run: |
-          conda info
-          conda list
-      - name: Run tests
-        shell: bash -l {0}
-        run: pytest completion_provider -vv
diff --git a/.github/workflows/windows-tests.yml b/.github/workflows/windows-tests.yml
deleted file mode 100644
index 57fea43..0000000
--- a/.github/workflows/windows-tests.yml
+++ /dev/null
@@ -1,74 +0,0 @@
-name: Windows tests
-
-on:
-  push:
-    branches:
-    - main
-  pull_request:
-    branches:
-    - main
-
-jobs:
-  windows:
-    name: Windows Py${{ matrix.PYTHON_VERSION }} spyder-from-${{ matrix.SPYDER_SOURCE }}
-    runs-on: windows-latest
-    env:
-      CI: True
-      PYTHON_VERSION: ${{ matrix.PYTHON_VERSION }}
-      RUNNER_OS: 'windows'
-    strategy:
-      fail-fast: false 
-      matrix:
-        PYTHON_VERSION: ['3.10']        
-        SPYDER_SOURCE: ['git']
-    steps:
-      - name: Checkout branch
-        uses: actions/checkout@v2
-      - name: Install Conda
-        uses: conda-incubator/setup-miniconda@v2
-        with:
-           activate-environment: test
-           auto-update-conda: true
-           auto-activate-base: false
-           python-version: ${{ matrix.PYTHON_VERSION }}
-           channels: conda-forge/label/spyder_kernels_rc,conda-forge,defaults
-           channel-priority: strict
-           miniforge-variant: Mambaforge
-      - name: Checkout Spyder from git
-        if: matrix.SPYDER_SOURCE == 'git'
-        uses: actions/checkout@v3
-        with:
-          repository: 'spyder-ide/spyder'
-          path: 'spyder'
-      - name: Install Spyder's dependencies (main)
-        if: matrix.SPYDER_SOURCE == 'git'
-        shell: bash -l {0}
-        run: conda env update --file spyder/requirements/main.yml
-      - name: Install Spyder from source
-        if: matrix.SPYDER_SOURCE == 'git'
-        shell: bash -l {0}
-        run: pip install -e spyder
-      - name: Install package dependencies (without Spyder)
-        if: matrix.SPYDER_SOURCE == 'git'
-        shell: bash -l {0}
-        run: |
-          python .github/scripts/generate-without-spyder.py
-          conda install --file requirements/without-spyder.txt -y
-      - name: Install package dependencies
-        if: matrix.SPYDER_SOURCE == 'conda'
-        shell: bash -l {0}
-        run: conda install --file requirements/conda.txt -y -q -c conda-forge
-      - name: Install test dependencies
-        shell: bash -l {0}
-        run: conda install -c spyder-ide --file requirements/tests.txt -y -q
-      - name: Install Package
-        shell: bash -l {0}
-        run: pip install --no-deps -e .
-      - name: Show environment information
-        shell: bash -l {0}
-        run: |
-          conda info
-          conda list
-      - name: Run tests
-        shell: bash -l {0}
-        run: pytest completion_provider -vv
diff --git a/langchain_provider/parsing/tests/__init__.py b/langchain_provider/parsing/tests/__init__.py
deleted file mode 100644
index dd237da..0000000
--- a/langchain_provider/parsing/tests/__init__.py
+++ /dev/null
@@ -1,4 +0,0 @@
-# -*- coding: utf-8 -*-
-
-# Copyright © Spyder Project Contributors
-# Licensed under the terms of the MIT License
diff --git a/langchain_provider/parsing/tests/test_parsing.py b/langchain_provider/parsing/tests/test_parsing.py
deleted file mode 100644
index 7b709da..0000000
--- a/langchain_provider/parsing/tests/test_parsing.py
+++ /dev/null
@@ -1,44 +0,0 @@
-# -*- coding: utf-8 -*-
-
-# Copyright © Spyder Project Contributors
-# Licensed under the terms of the MIT License
-
-
-from langchain_provider.parsing import find_returning_function_path
-
-
-def test_find_returning_function_path():
-    # maps expected definition value to file content
-    # $ marks the cursor position and will be removed before "parsing"
-    table = [
-        ['pd.read_csv', '''import pandas as pd
-df = pd.read_csv("a")
-df.$'''],
-        ['pd.read_csv', '''import pandas as pd
-df = pd.read_csv("a")
-df.a$'''],
-        ['pd.read_csv', '''import pandas as pd
-df = pd.read_csv("a")
-foo = df.$'''],
-        ['pd.read_csv', '''import pandas as pd
-df = pd.read_csv("a")
-foo = df.a$'''],
-        ['plt.figure', '''import matplotlib.pyplot as plt
-fig=plt.figure(figsize=(15, 10))
-fig.$'''],
-        ['sns.pairplot', '''import seaborn as sns
-g = sns.pairplot(temp[[u'Pclass', u'Sex', u'Age', u'Parch', u'Fare',
-    u'Embarked', u'FamilySize', u'Title', u'Survived']],
-    hue='Survived', palette = 'seismic',size=1.2,diag_kind = 'kde',
-    diag_kws=dict(shade=True),plot_kws=dict(s=10) )
-g.s$''']
-    ]
-
-    for k in table:
-        expected, content = k
-        offset = content.find('$')
-        content = content[0:offset]
-        print('Checking {}: {}\n'.format(
-            expected,
-            content.replace('\n', '\\n')))
-        assert expected == find_returning_function_path(content, offset)
diff --git a/requirements/tests.txt b/requirements/tests.txt
deleted file mode 100644
index 8787c51..0000000
--- a/requirements/tests.txt
+++ /dev/null
@@ -1,6 +0,0 @@
-pytest <7.0
-pytest-cov
-pytest-mock
-pytest-qt
-codecov
-flaky
\ No newline at end of file