diff --git a/.github/workflows/publish-workflow.yaml b/.github/workflows/publish-workflow.yaml index ebddb1f3cdc..6b8112f122e 100644 --- a/.github/workflows/publish-workflow.yaml +++ b/.github/workflows/publish-workflow.yaml @@ -57,12 +57,26 @@ jobs: username: ${{ github.repository_owner }} password: ${{ secrets.GHCR_PAT }} + - name: Build and push armv7 image + uses: docker/build-push-action@v5 + with: + context: . + file: docker/Dockerfile-armv7 + platforms: linux/arm/v7 + push: true + tags: | + hlohaus789/g4f:latest-armv7 + hlohaus789/g4f:${{ github.ref_name }}-armv7 + labels: ${{ steps.metadata.outputs.labels }} + build-args: | + G4F_VERSION=${{ github.ref_name }} + - name: Build and push small images uses: docker/build-push-action@v5 with: context: . file: docker/Dockerfile-slim - platforms: linux/amd64,linux/arm64,linux/arm/v7 + platforms: linux/amd64,linux/arm64 push: true tags: | hlohaus789/g4f:latest-slim diff --git a/docker/Dockerfile-armv7 b/docker/Dockerfile-armv7 new file mode 100644 index 00000000000..866ac63bc2b --- /dev/null +++ b/docker/Dockerfile-armv7 @@ -0,0 +1,67 @@ +FROM python:slim-bookworm + +ARG G4F_VERSION +ARG G4F_USER=g4f +ARG G4F_USER_ID=1000 +ARG PYDANTIC_VERSION=1.8.1 + +ENV G4F_VERSION $G4F_VERSION +ENV G4F_USER $G4F_USER +ENV G4F_USER_ID $G4F_USER_ID +ENV G4F_DIR /app + +RUN apt-get update && apt-get upgrade -y \ + && apt-get install -y git \ + && apt-get install --quiet --yes --no-install-recommends \ + build-essential \ +# Add user and user group + && groupadd -g $G4F_USER_ID $G4F_USER \ + && useradd -rm -G sudo -u $G4F_USER_ID -g $G4F_USER_ID $G4F_USER \ + && mkdir -p /var/log/supervisor \ + && chown "${G4F_USER_ID}:${G4F_USER_ID}" /var/log/supervisor \ + && echo "${G4F_USER}:${G4F_USER}" | chpasswd \ + && python -m pip install --upgrade pip + +USER $G4F_USER_ID +WORKDIR $G4F_DIR + +ENV HOME /home/$G4F_USER +ENV PATH "${HOME}/.local/bin:${PATH}" + +# Create app dir and copy the project's requirements file into it +RUN mkdir -p $G4F_DIR +COPY requirements-min.txt $G4F_DIR +COPY requirements-slim.txt $G4F_DIR + +# Upgrade pip for the latest features and install the project's Python dependencies. +RUN pip install --no-cache-dir -r requirements-min.txt \ + && pip install --no-cache-dir --no-binary setuptools \ + Cython==0.29.22 \ + setuptools \ + # Install PyDantic + && pip install \ + -vvv \ + --no-cache-dir \ + --no-binary :all: \ + --global-option=build_ext \ + --global-option=-j8 \ + pydantic==${PYDANTIC_VERSION} +RUN cat requirements-slim.txt | xargs -n 1 pip install --no-cache-dir || true + +# Remove build packages +RUN pip uninstall --yes \ + Cython \ + setuptools + +USER root + +# Clean up build deps +RUN apt-get purge --auto-remove --yes \ + build-essential \ + && apt-get clean \ + && rm --recursive --force /var/lib/apt/lists/* /tmp/* /var/tmp/* + +USER $G4F_USER_ID + +# Copy the entire package into the container. +ADD --chown=$G4F_USER:$G4F_USER g4f $G4F_DIR/g4f \ No newline at end of file diff --git a/docker/Dockerfile-slim b/docker/Dockerfile-slim index 0423814481f..dfc3344dcd0 100644 --- a/docker/Dockerfile-slim +++ b/docker/Dockerfile-slim @@ -29,11 +29,11 @@ ENV PATH "${HOME}/.local/bin:${PATH}" # Create app dir and copy the project's requirements file into it RUN mkdir -p $G4F_DIR -COPY requirements-min.txt $G4F_DIR COPY requirements-slim.txt $G4F_DIR # Upgrade pip for the latest features and install the project's Python dependencies. -RUN cat requirements-slim.txt | xargs -n 1 pip install --no-cache-dir || true +RUN pip install --no-cache-dir -r requirements-slim.txt \ + && pip install --no-cache-dir duckduckgo-search>=5.0 # Copy the entire package into the container. ADD --chown=$G4F_USER:$G4F_USER g4f $G4F_DIR/g4f \ No newline at end of file diff --git a/docs/async_client.md b/docs/async_client.md index e501aefa8a2..cc4c5806504 100644 --- a/docs/async_client.md +++ b/docs/async_client.md @@ -280,10 +280,9 @@ The G4F AsyncClient supports a wide range of AI models and providers, allowing y - OpenAI - Google (for Gemini) - Anthropic - - Bing + - Microsoft Copilot - Custom providers - **To use a specific model or provider, specify it when creating the client or in the API call:** ```python diff --git a/g4f/Provider/__init__.py b/g4f/Provider/__init__.py index 378f09c8e5b..e23f5f60112 100644 --- a/g4f/Provider/__init__.py +++ b/g4f/Provider/__init__.py @@ -14,7 +14,6 @@ from .AIUncensored import AIUncensored from .Airforce import Airforce from .AmigoChat import AmigoChat -from .Bing import Bing from .Blackbox import Blackbox from .ChatGpt import ChatGpt from .ChatGptEs import ChatGptEs diff --git a/g4f/Provider/Bing.py b/g4f/Provider/deprecated/Bing.py similarity index 97% rename from g4f/Provider/Bing.py rename to g4f/Provider/deprecated/Bing.py index cdc2b9d9e00..49bce146e42 100644 --- a/g4f/Provider/Bing.py +++ b/g4f/Provider/deprecated/Bing.py @@ -8,17 +8,17 @@ from urllib import parse from datetime import datetime, date -from ..typing import AsyncResult, Messages, ImageType, Cookies -from ..image import ImageRequest -from ..errors import ResponseError, ResponseStatusError, RateLimitError -from ..requests import DEFAULT_HEADERS -from ..requests.aiohttp import StreamSession -from .base_provider import AsyncGeneratorProvider, ProviderModelMixin -from .helper import get_random_hex -from .bing.upload_image import upload_image -from .bing.conversation import Conversation, create_conversation, delete_conversation -from .needs_auth.BingCreateImages import BingCreateImages -from .. import debug +from ...typing import AsyncResult, Messages, ImageType, Cookies +from ...image import ImageRequest +from ...errors import ResponseError, ResponseStatusError, RateLimitError +from ...requests import DEFAULT_HEADERS +from ...requests.aiohttp import StreamSession +from ..base_provider import AsyncGeneratorProvider, ProviderModelMixin +from ..helper import get_random_hex +from ..bing.upload_image import upload_image +from ..bing.conversation import Conversation, create_conversation, delete_conversation +from ..needs_auth.BingCreateImages import BingCreateImages +from ... import debug class Tones: """ @@ -35,7 +35,7 @@ class Bing(AsyncGeneratorProvider, ProviderModelMixin): """ label = "Microsoft Copilot in Bing" url = "https://bing.com/chat" - working = True + working = False supports_message_history = True default_model = "Balanced" default_vision_model = "gpt-4-vision" diff --git a/g4f/Provider/deprecated/__init__.py b/g4f/Provider/deprecated/__init__.py index 368a71a01bf..afb636e89b0 100644 --- a/g4f/Provider/deprecated/__init__.py +++ b/g4f/Provider/deprecated/__init__.py @@ -32,3 +32,4 @@ from .Hashnode import Hashnode from .Ylokh import Ylokh from .OpenAssistant import OpenAssistant +from .Bing import Bing \ No newline at end of file diff --git a/g4f/gui/client/static/css/style.css b/g4f/gui/client/static/css/style.css index 856f9fb5878..977a8908a21 100644 --- a/g4f/gui/client/static/css/style.css +++ b/g4f/gui/client/static/css/style.css @@ -108,6 +108,25 @@ body { border: 1px solid var(--blur-border); } +.new_version { + position: absolute; + right: 0; + top: 0; + padding: 10px; + font-weight: 500; + background-color: rgba(0, 0, 0, 0.5); + color: var(--colour-3); +} + +.white .new_version { + color: var(--colour-1); +} + +.new_version a { + color: var(--colour-4); + text-decoration: underline dotted; +} + .conversations { max-width: 300px; padding: var(--section-gap); diff --git a/g4f/gui/client/static/js/chat.v1.js b/g4f/gui/client/static/js/chat.v1.js index fd9cc50e882..0bf49ac31d5 100644 --- a/g4f/gui/client/static/js/chat.v1.js +++ b/g4f/gui/client/static/js/chat.v1.js @@ -1331,15 +1331,21 @@ async function load_version() { document.title = 'g4f - ' + versions["version"]; let text = "version ~ " if (versions["version"] != versions["latest_version"]) { - let release_url = 'https://github.com/xtekky/gpt4free/releases/tag/' + versions["latest_version"]; + let release_url = 'https://github.com/xtekky/gpt4free/releases/latest'; let title = `New version: ${versions["latest_version"]}`; text += `${versions["version"]} 🆕`; + const new_version = document.createElement("div"); + new_version.classList.add("new_version"); + const link = `v${versions["latest_version"]}`; + new_version.innerHTML = `g4f ${link}  ðŸ†•`; + new_version.addEventListener("click", ()=>new_version.parentElement.removeChild(new_version)); + document.body.appendChild(new_version); } else { text += versions["version"]; } document.getElementById("version_text").innerHTML = text } -setTimeout(load_version, 2000); +setTimeout(load_version, 100); [imageInput, cameraInput].forEach((el) => { el.addEventListener('click', async () => { diff --git a/requirements-slim.txt b/requirements-slim.txt index 2377faa3900..a7e105db282 100644 --- a/requirements-slim.txt +++ b/requirements-slim.txt @@ -3,7 +3,6 @@ pycryptodome curl_cffi>=0.6.2 aiohttp certifi -duckduckgo-search>=5.0 nest_asyncio werkzeug pillow