added [browser] extra; refac the pip install utils

This commit is contained in:
Paul Gauthier 2024-07-14 17:22:17 +01:00
parent 057c1af449
commit 76dad84285
13 changed files with 257 additions and 151 deletions

View file

@ -6,8 +6,8 @@ from pathlib import Path
import git import git
from aider import models, prompts, voice from aider import models, prompts, utils, voice
from aider.help import Help, PipInstallHF from aider.help import Help
from aider.llm import litellm from aider.llm import litellm
from aider.scrape import Scraper from aider.scrape import Scraper
from aider.utils import is_image_file from aider.utils import is_image_file
@ -662,19 +662,22 @@ class Commands:
from aider.coders import Coder from aider.coders import Coder
if not self.help: if not self.help:
try: pip_install_cmd = [
self.help = Help() "aider-chat[hf-embed]",
except PipInstallHF as err: "--extra-index-url",
self.io.tool_error(str(err)) "https://download.pytorch.org/whl/cpu",
if self.io.confirm_ask("Run pip install?", default="y"): ]
try: res = utils.check_pip_install_extra(
self.help = Help(pip_install=True) self.io,
except PipInstallHF: "llama_index.embeddings.huggingface",
pass "To use interactive /help you need to install HuggingFace embeddings",
pip_install_cmd,
)
if not res:
self.io.tool_error("Unable to initialize interactive help.")
return
if not self.help: self.help = Help()
self.io.tool_error("Unable to initialize interactive help.")
return
coder = Coder.create( coder = Coder.create(
main_model=self.coder.main_model, main_model=self.coder.main_model,

View file

@ -6,7 +6,7 @@ from pathlib import Path
import importlib_resources import importlib_resources
from aider import __version__, utils from aider import __version__
from aider.dump import dump # noqa: F401 from aider.dump import dump # noqa: F401
from aider.help_pats import exclude_website_pats from aider.help_pats import exclude_website_pats
@ -87,35 +87,10 @@ def get_index():
return index return index
class PipInstallHF(Exception):
pass
pip_install_cmd = [
"aider-chat[hf-embed]",
"--extra-index-url",
"https://download.pytorch.org/whl/cpu",
]
pip_install_error = """
To use interactive /help you need to install HuggingFace embeddings:
{cmd}
""" # noqa: E231
class Help: class Help:
def __init__(self, pip_install=False): def __init__(self, pip_install=False):
cmd = utils.get_pip_install(pip_install_cmd) from llama_index.core import Settings
if pip_install: from llama_index.embeddings.huggingface import HuggingFaceEmbedding
utils.run_install(cmd)
try:
from llama_index.core import Settings
from llama_index.embeddings.huggingface import HuggingFaceEmbedding
except ImportError:
raise PipInstallHF(pip_install_error.format(cmd=' '.join(cmd)))
os.environ["TOKENIZERS_PARALLELISM"] = "true" os.environ["TOKENIZERS_PARALLELISM"] = "true"
Settings.embed_model = HuggingFaceEmbedding(model_name="BAAI/bge-small-en-v1.5") Settings.embed_model = HuggingFaceEmbedding(model_name="BAAI/bge-small-en-v1.5")

View file

@ -148,6 +148,15 @@ def scrub_sensitive_info(args, text):
return text return text
def check_streamlit_install(io):
return utils.check_pip_install_extra(
io,
"streamlit",
"You need to install the aider browser feature",
["aider-chat[browser]"],
)
def launch_gui(args): def launch_gui(args):
from streamlit.web import cli from streamlit.web import cli
@ -318,10 +327,6 @@ def main(argv=None, input=None, output=None, force_git_root=None, return_coder=F
litellm.client_session = httpx.Client(verify=False) litellm.client_session = httpx.Client(verify=False)
if args.gui and not return_coder:
launch_gui(argv)
return
if args.dark_mode: if args.dark_mode:
args.user_input_color = "#32FF32" args.user_input_color = "#32FF32"
args.tool_error_color = "#FF3333" args.tool_error_color = "#FF3333"
@ -355,6 +360,12 @@ def main(argv=None, input=None, output=None, force_git_root=None, return_coder=F
editingmode=editing_mode, editingmode=editing_mode,
) )
if args.gui and not return_coder:
if not check_streamlit_install(io):
return
launch_gui(argv)
return
for fname in loaded_dotenvs: for fname in loaded_dotenvs:
io.tool_output(f"Loaded {fname}") io.tool_output(f"Loaded {fname}")

View file

@ -1,8 +1,8 @@
import itertools
import os import os
import subprocess import subprocess
import sys import sys
import tempfile import tempfile
import itertools
from pathlib import Path from pathlib import Path
import git import git
@ -182,7 +182,6 @@ def split_chat_history_markdown(text, include_tool=False):
def get_pip_install(args): def get_pip_install(args):
cmd = [ cmd = [
sys.executable, sys.executable,
"-m", "-m",
@ -192,14 +191,22 @@ def get_pip_install(args):
cmd += args cmd += args
return cmd return cmd
def run_install(cmd): def run_install(cmd):
print() print()
print("Installing: ", ' '.join(cmd)) print("Installing: ", " ".join(cmd))
try: try:
process = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, text=True, bufsize=1, universal_newlines=True)
output = [] output = []
spinner = itertools.cycle(['', '', '', '', '', '', '', '', '', '']) process = subprocess.Popen(
cmd,
stdout=subprocess.PIPE,
stderr=subprocess.STDOUT,
text=True,
bufsize=1,
universal_newlines=True,
)
spinner = itertools.cycle(["", "", "", "", "", "", "", "", "", ""])
for line in process.stdout: for line in process.stdout:
output.append(line) output.append(line)
@ -208,14 +215,45 @@ def run_install(cmd):
return_code = process.wait() return_code = process.wait()
if return_code == 0: if return_code == 0:
print("\rInstallation completed successfully.") print("\rInstallation complete.")
print() print()
return True return True, output
except subprocess.CalledProcessError as e: except subprocess.CalledProcessError as e:
print(f"\nError running pip install: {e}") print(f"\nError running pip install: {e}")
print("\nInstallation failed.\n") print("\nInstallation failed.\n")
return False, output
def check_pip_install_extra(io, module, prompt, pip_install_cmd):
try:
__import__(module)
return True
except (ImportError, ModuleNotFoundError):
pass
cmd = get_pip_install(pip_install_cmd)
text = f"{prompt}:\n\n{' '.join(cmd)}\n\n"
io.tool_error(text)
if not io.confirm_ask("Run pip install?", default="y"):
return
success, output = run_install(cmd)
if not success:
return
try:
__import__(module)
return True
except (ImportError, ModuleNotFoundError):
pass
for line in output: for line in output:
print(line) print(line)
print()
print(f"Failed to install {pip_install_cmd[0]}")

View file

@ -49,7 +49,8 @@ Newer aider version v{latest_version} is available. To upgrade, run:
io.tool_error(text) io.tool_error(text)
if io.confirm_ask("Run pip install?"): if io.confirm_ask("Run pip install?"):
if utils.run_install(cmd): success, _output = utils.run_install(cmd)
if success:
io.tool_output("Re-run aider to use new version.") io.tool_output("Re-run aider to use new version.")
sys.exit() sys.exit()

View file

@ -8,8 +8,6 @@ aiohttp==3.9.5
# via litellm # via litellm
aiosignal==1.3.1 aiosignal==1.3.1
# via aiohttp # via aiohttp
altair==5.3.0
# via streamlit
annotated-types==0.7.0 annotated-types==0.7.0
# via pydantic # via pydantic
anyio==4.4.0 anyio==4.4.0
@ -25,12 +23,8 @@ backoff==2.2.1
# via -r requirements/requirements.in # via -r requirements/requirements.in
beautifulsoup4==4.12.3 beautifulsoup4==4.12.3
# via -r requirements/requirements.in # via -r requirements/requirements.in
blinker==1.8.2
# via streamlit
cachetools==5.3.3 cachetools==5.3.3
# via # via google-auth
# google-auth
# streamlit
certifi==2024.7.4 certifi==2024.7.4
# via # via
# httpcore # httpcore
@ -43,9 +37,7 @@ cffi==1.16.0
charset-normalizer==3.3.2 charset-normalizer==3.3.2
# via requests # via requests
click==8.1.7 click==8.1.7
# via # via litellm
# litellm
# streamlit
configargparse==1.7 configargparse==1.7
# via -r requirements/requirements.in # via -r requirements/requirements.in
diff-match-patch==20230430 diff-match-patch==20230430
@ -67,9 +59,7 @@ fsspec==2024.6.1
gitdb==4.0.11 gitdb==4.0.11
# via gitpython # via gitpython
gitpython==3.1.43 gitpython==3.1.43
# via # via -r requirements/requirements.in
# -r requirements/requirements.in
# streamlit
google-ai-generativelanguage==0.6.6 google-ai-generativelanguage==0.6.6
# via google-generativeai # via google-generativeai
google-api-core[grpc]==2.19.1 google-api-core[grpc]==2.19.1
@ -129,14 +119,10 @@ importlib-metadata==7.2.1
importlib-resources==6.4.0 importlib-resources==6.4.0
# via -r requirements/requirements.in # via -r requirements/requirements.in
jinja2==3.1.4 jinja2==3.1.4
# via # via litellm
# altair
# litellm
# pydeck
jsonschema==4.22.0 jsonschema==4.22.0
# via # via
# -r requirements/requirements.in # -r requirements/requirements.in
# altair
# litellm # litellm
jsonschema-specifications==2023.12.1 jsonschema-specifications==2023.12.1
# via jsonschema # via jsonschema
@ -159,32 +145,19 @@ networkx==3.2.1
numpy==1.26.4 numpy==1.26.4
# via # via
# -r requirements/requirements.in # -r requirements/requirements.in
# altair
# pandas
# pyarrow
# pydeck
# scipy # scipy
# streamlit
openai==1.35.10 openai==1.35.10
# via litellm # via litellm
packaging==24.1 packaging==24.1
# via # via
# -r requirements/requirements.in # -r requirements/requirements.in
# altair
# huggingface-hub # huggingface-hub
# streamlit
pandas==2.2.2
# via
# altair
# streamlit
pathspec==0.12.1 pathspec==0.12.1
# via # via
# -r requirements/requirements.in # -r requirements/requirements.in
# grep-ast # grep-ast
pillow==10.4.0 pillow==10.4.0
# via # via -r requirements/requirements.in
# -r requirements/requirements.in
# streamlit
playwright==1.45.0 playwright==1.45.0
# via -r requirements/requirements.in # via -r requirements/requirements.in
prompt-toolkit==3.0.47 prompt-toolkit==3.0.47
@ -201,9 +174,6 @@ protobuf==4.25.3
# googleapis-common-protos # googleapis-common-protos
# grpcio-status # grpcio-status
# proto-plus # proto-plus
# streamlit
pyarrow==16.1.0
# via streamlit
pyasn1==0.6.0 pyasn1==0.6.0
# via # via
# pyasn1-modules # pyasn1-modules
@ -221,8 +191,6 @@ pydantic==2.8.2
# openai # openai
pydantic-core==2.20.1 pydantic-core==2.20.1
# via pydantic # via pydantic
pydeck==0.9.1
# via streamlit
pyee==11.1.0 pyee==11.1.0
# via playwright # via playwright
pyflakes==3.2.0 pyflakes==3.2.0
@ -233,12 +201,8 @@ pypandoc==1.13
# via -r requirements/requirements.in # via -r requirements/requirements.in
pyparsing==3.1.2 pyparsing==3.1.2
# via httplib2 # via httplib2
python-dateutil==2.9.0.post0
# via pandas
python-dotenv==1.0.1 python-dotenv==1.0.1
# via litellm # via litellm
pytz==2024.1
# via pandas
pyyaml==6.0.1 pyyaml==6.0.1
# via # via
# -r requirements/requirements.in # -r requirements/requirements.in
@ -254,12 +218,9 @@ requests==2.32.3
# google-api-core # google-api-core
# huggingface-hub # huggingface-hub
# litellm # litellm
# streamlit
# tiktoken # tiktoken
rich==13.7.1 rich==13.7.1
# via # via -r requirements/requirements.in
# -r requirements/requirements.in
# streamlit
rpds-py==0.18.1 rpds-py==0.18.1
# via # via
# jsonschema # jsonschema
@ -268,8 +229,6 @@ rsa==4.9
# via google-auth # via google-auth
scipy==1.13.1 scipy==1.13.1
# via -r requirements/requirements.in # via -r requirements/requirements.in
six==1.16.0
# via python-dateutil
smmap==5.0.1 smmap==5.0.1
# via gitdb # via gitdb
sniffio==1.3.1 sniffio==1.3.1
@ -283,20 +242,10 @@ soundfile==0.12.1
# via -r requirements/requirements.in # via -r requirements/requirements.in
soupsieve==2.5 soupsieve==2.5
# via beautifulsoup4 # via beautifulsoup4
streamlit==1.36.0
# via -r requirements/requirements.in
tenacity==8.4.2
# via streamlit
tiktoken==0.7.0 tiktoken==0.7.0
# via litellm # via litellm
tokenizers==0.19.1 tokenizers==0.19.1
# via litellm # via litellm
toml==0.10.2
# via streamlit
toolz==0.12.1
# via altair
tornado==6.4.1
# via streamlit
tqdm==4.66.4 tqdm==4.66.4
# via # via
# google-generativeai # google-generativeai
@ -316,15 +265,10 @@ typing-extensions==4.12.2
# pydantic # pydantic
# pydantic-core # pydantic-core
# pyee # pyee
# streamlit
tzdata==2024.1
# via pandas
uritemplate==4.1.1 uritemplate==4.1.1
# via google-api-python-client # via google-api-python-client
urllib3==2.2.2 urllib3==2.2.2
# via requests # via requests
watchdog==4.0.1
# via -r requirements/requirements.in
wcwidth==0.2.13 wcwidth==0.2.13
# via prompt-toolkit # via prompt-toolkit
yarl==1.9.4 yarl==1.9.4

View file

@ -0,0 +1,4 @@
-c ../requirements.txt
streamlit
watchdog

View file

@ -0,0 +1,151 @@
#
# This file is autogenerated by pip-compile with Python 3.12
# by the following command:
#
# pip-compile --output-file=requirements/requirements-browser.txt requirements/requirements-browser.in
#
altair==5.3.0
# via streamlit
attrs==23.2.0
# via
# -c requirements/../requirements.txt
# jsonschema
# referencing
blinker==1.8.2
# via streamlit
cachetools==5.3.3
# via
# -c requirements/../requirements.txt
# streamlit
certifi==2024.7.4
# via
# -c requirements/../requirements.txt
# requests
charset-normalizer==3.3.2
# via
# -c requirements/../requirements.txt
# requests
click==8.1.7
# via
# -c requirements/../requirements.txt
# streamlit
gitdb==4.0.11
# via
# -c requirements/../requirements.txt
# gitpython
gitpython==3.1.43
# via
# -c requirements/../requirements.txt
# streamlit
idna==3.7
# via
# -c requirements/../requirements.txt
# requests
jinja2==3.1.4
# via
# -c requirements/../requirements.txt
# altair
# pydeck
jsonschema==4.22.0
# via
# -c requirements/../requirements.txt
# altair
jsonschema-specifications==2023.12.1
# via
# -c requirements/../requirements.txt
# jsonschema
markdown-it-py==3.0.0
# via
# -c requirements/../requirements.txt
# rich
markupsafe==2.1.5
# via
# -c requirements/../requirements.txt
# jinja2
mdurl==0.1.2
# via
# -c requirements/../requirements.txt
# markdown-it-py
numpy==1.26.4
# via
# -c requirements/../requirements.txt
# altair
# pandas
# pyarrow
# pydeck
# streamlit
packaging==24.1
# via
# -c requirements/../requirements.txt
# altair
# streamlit
pandas==2.2.2
# via
# altair
# streamlit
pillow==10.4.0
# via
# -c requirements/../requirements.txt
# streamlit
protobuf==4.25.3
# via
# -c requirements/../requirements.txt
# streamlit
pyarrow==16.1.0
# via streamlit
pydeck==0.9.1
# via streamlit
pygments==2.18.0
# via
# -c requirements/../requirements.txt
# rich
python-dateutil==2.9.0.post0
# via pandas
pytz==2024.1
# via pandas
referencing==0.35.1
# via
# -c requirements/../requirements.txt
# jsonschema
# jsonschema-specifications
requests==2.32.3
# via
# -c requirements/../requirements.txt
# streamlit
rich==13.7.1
# via
# -c requirements/../requirements.txt
# streamlit
rpds-py==0.18.1
# via
# -c requirements/../requirements.txt
# jsonschema
# referencing
six==1.16.0
# via python-dateutil
smmap==5.0.1
# via
# -c requirements/../requirements.txt
# gitdb
streamlit==1.36.0
# via -r requirements/requirements-browser.in
tenacity==8.4.2
# via streamlit
toml==0.10.2
# via streamlit
toolz==0.12.1
# via altair
tornado==6.4.1
# via streamlit
typing-extensions==4.12.2
# via
# -c requirements/../requirements.txt
# streamlit
tzdata==2024.1
# via pandas
urllib3==2.2.2
# via
# -c requirements/../requirements.txt
# requests
watchdog==4.0.1
# via -r requirements/requirements-browser.in

View file

@ -99,9 +99,7 @@ packaging==24.1
# pytest # pytest
# sphinx # sphinx
pandas==2.2.2 pandas==2.2.2
# via # via -r requirements/requirements-dev.in
# -c requirements/../requirements.txt
# -r requirements/requirements-dev.in
pathos==0.3.2 pathos==0.3.2
# via lox # via lox
pillow==10.4.0 pillow==10.4.0
@ -137,13 +135,10 @@ pytest==8.2.2
# via -r requirements/requirements-dev.in # via -r requirements/requirements-dev.in
python-dateutil==2.9.0.post0 python-dateutil==2.9.0.post0
# via # via
# -c requirements/../requirements.txt
# matplotlib # matplotlib
# pandas # pandas
pytz==2024.1 pytz==2024.1
# via # via pandas
# -c requirements/../requirements.txt
# pandas
pyyaml==6.0.1 pyyaml==6.0.1
# via # via
# -c requirements/../requirements.txt # -c requirements/../requirements.txt
@ -159,9 +154,7 @@ rich==13.7.1
shellingham==1.5.4 shellingham==1.5.4
# via typer # via typer
six==1.16.0 six==1.16.0
# via # via python-dateutil
# -c requirements/../requirements.txt
# python-dateutil
snowballstemmer==2.2.0 snowballstemmer==2.2.0
# via sphinx # via sphinx
sphinx==7.3.7 sphinx==7.3.7
@ -191,9 +184,7 @@ typing-extensions==4.12.2
# -c requirements/../requirements.txt # -c requirements/../requirements.txt
# typer # typer
tzdata==2024.1 tzdata==2024.1
# via # via pandas
# -c requirements/../requirements.txt
# pandas
urllib3==2.2.2 urllib3==2.2.2
# via # via
# -c requirements/../requirements.txt # -c requirements/../requirements.txt

View file

@ -161,9 +161,7 @@ packaging==24.1
# marshmallow # marshmallow
# transformers # transformers
pandas==2.2.2 pandas==2.2.2
# via # via llama-index-core
# -c requirements/../requirements.txt
# llama-index-core
pillow==10.4.0 pillow==10.4.0
# via # via
# -c requirements/../requirements.txt # -c requirements/../requirements.txt
@ -179,13 +177,9 @@ pydantic-core==2.20.1
# -c requirements/../requirements.txt # -c requirements/../requirements.txt
# pydantic # pydantic
python-dateutil==2.9.0.post0 python-dateutil==2.9.0.post0
# via # via pandas
# -c requirements/../requirements.txt
# pandas
pytz==2024.1 pytz==2024.1
# via # via pandas
# -c requirements/../requirements.txt
# pandas
pyyaml==6.0.1 pyyaml==6.0.1
# via # via
# -c requirements/../requirements.txt # -c requirements/../requirements.txt
@ -217,9 +211,7 @@ scipy==1.13.1
sentence-transformers==3.0.1 sentence-transformers==3.0.1
# via llama-index-embeddings-huggingface # via llama-index-embeddings-huggingface
six==1.16.0 six==1.16.0
# via # via python-dateutil
# -c requirements/../requirements.txt
# python-dateutil
sniffio==1.3.1 sniffio==1.3.1
# via # via
# -c requirements/../requirements.txt # -c requirements/../requirements.txt
@ -233,9 +225,7 @@ sqlalchemy[asyncio]==2.0.31
sympy==1.13.0 sympy==1.13.0
# via torch # via torch
tenacity==8.4.2 tenacity==8.4.2
# via # via llama-index-core
# -c requirements/../requirements.txt
# llama-index-core
threadpoolctl==3.5.0 threadpoolctl==3.5.0
# via scikit-learn # via scikit-learn
tiktoken==0.7.0 tiktoken==0.7.0
@ -275,9 +265,7 @@ typing-inspect==0.9.0
# dataclasses-json # dataclasses-json
# llama-index-core # llama-index-core
tzdata==2024.1 tzdata==2024.1
# via # via pandas
# -c requirements/../requirements.txt
# pandas
urllib3==2.2.2 urllib3==2.2.2
# via # via
# -c requirements/../requirements.txt # -c requirements/../requirements.txt

View file

@ -23,8 +23,6 @@ playwright
pypandoc pypandoc
litellm litellm
google-generativeai google-generativeai
streamlit
watchdog
flake8 flake8
importlib_resources importlib_resources

View file

@ -8,8 +8,8 @@ pip-compile \
--output-file=requirements.txt \ --output-file=requirements.txt \
$1 $1
for SUFFIX in dev hf-embed ; do for SUFFIX in dev hf-embed browser; do
echo suffix: ${SUFFIX}
pip-compile \ pip-compile \
requirements/requirements-${SUFFIX}.in \ requirements/requirements-${SUFFIX}.in \
--output-file=requirements/requirements-${SUFFIX}.txt \ --output-file=requirements/requirements-${SUFFIX}.txt \

View file

@ -22,6 +22,7 @@ def get_requirements(suffix=""):
requirements = get_requirements() requirements = get_requirements()
dev_requirements = get_requirements("dev") dev_requirements = get_requirements("dev")
hf_requirements = get_requirements("hf-embed") hf_requirements = get_requirements("hf-embed")
browser_requirements = get_requirements("browser")
# README # README
with open("README.md", "r", encoding="utf-8") as f: with open("README.md", "r", encoding="utf-8") as f:
@ -47,6 +48,7 @@ setup(
extras_require={ extras_require={
"dev": dev_requirements, "dev": dev_requirements,
"hf-embed": hf_requirements, "hf-embed": hf_requirements,
"browser": browser_requirements,
}, },
python_requires=">=3.9,<3.13", python_requires=">=3.9,<3.13",
entry_points={ entry_points={