Skip to content

Commit

Permalink
pyRobBot v0.1.0
Browse files Browse the repository at this point in the history
  • Loading branch information
paulovcmedeiros committed Nov 10, 2023
2 parents d6de2d4 + 6659c42 commit 5cbadcb
Show file tree
Hide file tree
Showing 23 changed files with 102 additions and 29 deletions.
75 changes: 75 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
[![GitHub](https://img.shields.io/badge/github-%23121011.svg?style=for-the-badge&logo=github&logoColor=white)](https://github.com/paulovcmedeiros/pyRobBot)


[![Contributors Welcome](https://img.shields.io/badge/Contributors-welcome-<COLOR>.svg)](https://github.com/paulovcmedeiros/pyRobBot/pulls)
[![Linting](https://github.com/paulovcmedeiros/pyRobBot/actions/workflows/linting.yaml/badge.svg)](https://github.com/paulovcmedeiros/pyRobBot/actions/workflows/linting.yaml)
[![Tests](https://github.com/paulovcmedeiros/pyRobBot/actions/workflows/tests.yaml/badge.svg)](https://github.com/paulovcmedeiros/pyRobBot/actions/workflows/tests.yaml)
[![codecov](https://codecov.io/gh/paulovcmedeiros/pyRobBot/graph/badge.svg?token=XI8G1WH9O6)](https://codecov.io/gh/paulovcmedeiros/pyRobBot)

# pyRobBot

A simple chatbot that uses the OpenAI API to get responses from [GPT LLMs](https://platform.openai.com/docs/models) via OpenAI API. Written in Python with a Web UI made with [Streamlit](https://streamlit.io). Can also be used directly from the terminal.

See also the [online documentation](https://paulovcmedeiros.github.io/pyRobBot-docs).

## Features
- [x] Web UI
- Add/remove conversations dynamically
- [x] Fully configurable
- Support for multiple GPT LLMs
- Control over the parameters passed to the OpenAI API, with (hopefully) sensible defaults
- Ability o modify the chat parameters in the same conversation
- Each conversation has its own parameters
- [x] Autosave and retrieve chat history
- [x] Chat context handling using [embeddings](https://platform.openai.com/docs/guides/embeddings)
- [x] Kepp track of estimated token usage and associated API call costs
- [x] Terminal UI


## System Requirements
- Python >= 3.9
- A valid [OpenAI API key](https://platform.openai.com/account/api-keys)
- Set in the Web UI or through the environment variable `OPENAI_API_KEY`

## Installation
### Using pip
```shell
pip install pyrobbot
```

### From source
```shell
pip install git+https://github.com/paulovcmedeiros/pyRobBot.git
```

## Basic Usage
Upon succesfull installation, you should be able to run
```shell
rob [opts] SUBCOMMAND [subcommand_opts]
```
where `[opts]` and `[subcommand_opts]` denote optional command line arguments
that apply, respectively, to `rob` in general and to `SUBCOMMAND`
specifically.

**Please run `rob -h` for information** about the supported subcommands
and general `rob` options. For info about specific subcommands and the
options that apply to them only, **please run `rob SUBCOMMAND -h`** (note
that the `-h` goes after the subcommand in this case).

### Using the Web UI
```shell
rob
```

### Running on the Terminal
```shell
rob .
```
## Disclaimers
This project's main purpose is to serve as a learning exercise for me (the author) and to serve as tool for and experimenting with OpenAI API and GPT LLMs. It does not aim to be the best or more robust OpenAI-powered chatbot out there.

Having said this, this project *does* aim to have a friendly user interface and to be easy to use and configure. So, please feel free to open an issue or submit a pull request if you find a bug or have a suggestion.

Last but not least: this project is **not** affiliated with OpenAI in any way.


6 changes: 3 additions & 3 deletions pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
[tool.poetry]
authors = ["Paulo V C Medeiros <[email protected]>"]
description = "A simple UI & terminal ChatGPT chatbot that uses OpenAI API."
description = "A simple UI & terminal chatbot that uses the OpenAI API."
license = "MIT"
name = "gpt-buddy-bot"
name = "pyrobbot"
readme = "README.md"
version = "0.1.0"

Expand All @@ -11,7 +11,7 @@
requires = ["poetry-core"]

[tool.poetry.scripts]
gbb = "gpt_buddy_bot.__main__:main"
rob = "pyrobbot.__main__:main"

[tool.poetry.dependencies]
# Python version
Expand Down
2 changes: 1 addition & 1 deletion gpt_buddy_bot/__init__.py → pyrobbot/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ class GeneralConstants:
CHAT_CACHE_DIR = PACKAGE_CACHE_DIRECTORY / "chats"

# Constants related to the app
APP_NAME = PACKAGE_NAME.title().replace("Gpt", "GPT").replace("_", " ")
APP_NAME = "pyRobBot"
APP_DIR = PACKAGE_DIRECTORY / "app"
APP_PATH = APP_DIR / "app.py"
PARSED_ARGS_FILE = PACKAGE_TMPDIR / f"parsed_args_{RUN_ID}.pkl"
Expand Down
File renamed without changes.
File renamed without changes.
File renamed without changes.
4 changes: 2 additions & 2 deletions gpt_buddy_bot/app/app.py → pyrobbot/app/app.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
"""Entrypoint for the package's UI."""
from gpt_buddy_bot import GeneralConstants
from gpt_buddy_bot.app.multipage import MultipageChatbotApp
from pyrobbot import GeneralConstants
from pyrobbot.app.multipage import MultipageChatbotApp


def run_app():
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,10 @@
import streamlit as st
from PIL import Image

from gpt_buddy_bot import GeneralConstants
from gpt_buddy_bot.chat import Chat
from gpt_buddy_bot.chat_configs import ChatOptions
from gpt_buddy_bot.openai_utils import CannotConnectToApiError
from pyrobbot import GeneralConstants
from pyrobbot.chat import Chat
from pyrobbot.chat_configs import ChatOptions
from pyrobbot.openai_utils import CannotConnectToApiError

_AVATAR_FILES_DIR = GeneralConstants.APP_DIR / "data"
_ASSISTANT_AVATAR_FILE_PATH = _AVATAR_FILES_DIR / "assistant_avatar.png"
Expand Down
File renamed without changes
File renamed without changes
8 changes: 4 additions & 4 deletions gpt_buddy_bot/app/multipage.py → pyrobbot/app/multipage.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,10 @@
import streamlit as st
from pydantic import ValidationError

from gpt_buddy_bot import GeneralConstants
from gpt_buddy_bot.app.app_page_templates import AppPage, ChatBotPage, _RecoveredChat
from gpt_buddy_bot.chat import Chat
from gpt_buddy_bot.chat_configs import ChatOptions
from pyrobbot import GeneralConstants
from pyrobbot.app.app_page_templates import AppPage, ChatBotPage, _RecoveredChat
from pyrobbot.chat import Chat
from pyrobbot.chat_configs import ChatOptions


class AbstractMultipageApp(ABC):
Expand Down
File renamed without changes.
File renamed without changes.
6 changes: 2 additions & 4 deletions gpt_buddy_bot/chat_configs.py → pyrobbot/chat_configs.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@

from pydantic import BaseModel, Field

from gpt_buddy_bot import GeneralConstants
from pyrobbot import GeneralConstants


class BaseConfigModel(BaseModel):
Expand Down Expand Up @@ -124,9 +124,7 @@ class ChatOptions(OpenAiApiCallOptions):
"""Model for the chat's configuration options."""

username: str = Field(default=getuser(), description="Name of the chat's user")
assistant_name: str = Field(
default=GeneralConstants.APP_NAME, description="Name of the chat's assistant"
)
assistant_name: str = Field(default="Rob", description="Name of the chat's assistant")
system_name: str = Field(
default=f"{GeneralConstants.PACKAGE_NAME}_system",
description="Name of the chat's system",
Expand Down
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
10 changes: 5 additions & 5 deletions tests/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,9 @@
import openai
import pytest

import gpt_buddy_bot
from gpt_buddy_bot.chat import Chat
from gpt_buddy_bot.chat_configs import ChatOptions
import pyrobbot
from pyrobbot.chat import Chat
from pyrobbot.chat_configs import ChatOptions


# Register markers and constants
Expand All @@ -22,7 +22,7 @@ def pytest_configure(config):
)

pytest.ORIGINAL_PACKAGE_CACHE_DIRECTORY = (
gpt_buddy_bot.GeneralConstants.PACKAGE_CACHE_DIRECTORY
pyrobbot.GeneralConstants.PACKAGE_CACHE_DIRECTORY
)


Expand All @@ -35,7 +35,7 @@ def _set_env():

@pytest.fixture(autouse=True)
def _mocked_general_constants(tmp_path):
gpt_buddy_bot.GeneralConstants.PACKAGE_CACHE_DIRECTORY = tmp_path / "cache"
pyrobbot.GeneralConstants.PACKAGE_CACHE_DIRECTORY = tmp_path / "cache"


@pytest.fixture(autouse=True)
Expand Down
4 changes: 2 additions & 2 deletions tests/smoke/test_app.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
from gpt_buddy_bot.app import app
from pyrobbot.app import app


def test_app(mocker, default_chat_configs):
mocker.patch("streamlit.session_state", {})
mocker.patch(
"gpt_buddy_bot.chat_configs.ChatOptions.from_file",
"pyrobbot.chat_configs.ChatOptions.from_file",
return_value=default_chat_configs,
)
app.run_app()
4 changes: 2 additions & 2 deletions tests/smoke/test_commands.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import pytest

from gpt_buddy_bot.__main__ import main
from gpt_buddy_bot.argparse_wrapper import get_parsed_args
from pyrobbot.__main__ import main
from pyrobbot.argparse_wrapper import get_parsed_args


@pytest.mark.usefixtures("_input_builtin_mocker")
Expand Down
4 changes: 2 additions & 2 deletions tests/unit/test_chat.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import openai
import pytest

from gpt_buddy_bot import GeneralConstants
from gpt_buddy_bot.openai_utils import CannotConnectToApiError
from pyrobbot import GeneralConstants
from pyrobbot.openai_utils import CannotConnectToApiError


@pytest.mark.order(1)
Expand Down

0 comments on commit 5cbadcb

Please sign in to comment.