Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feature/mdb ai integration #16

Merged
merged 2 commits into from
Jun 6, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 0 additions & 8 deletions .bumpversion.cfg

This file was deleted.

21 changes: 0 additions & 21 deletions .editorconfig

This file was deleted.

136 changes: 77 additions & 59 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,13 +1,11 @@
## Hey! - Your AI-powered Pair Programming Friend

> :warning: - You need OpenAI auth token to make Hey work.
> :sparkles: - You need a MindsDB token to use Hey. You can generate one for your personal uses for free from [here](mdb.ai)!

> :basecamp: - Watch this YouTube <a href="https://www.youtube.com/watch?v=fhO34PVa-38&list=LL&index=9">introduction video</a> about Hey!

> :writing_hand: - Read the <a href="https://blog.imsadra.me/introducing-hey-your-ai-powered-pair-programming-friend">"Introducing Hey! - Your AI-powered Pair Programming Friend"</a> article about the creation process, development phases, and a detailed overview of Hey.

> :package: - Check out <a href="https://pypi.org/project/hey-mindsdb/">Hey on PyPI</a>.

Hey is a CLI-based AI assistant that is powered by the ChatGPT AI model versions supported by [MindsDB](https://mindsdb.com/). This project is designed for [Hashnode X MindsDB](https://hashnode.com/hackathons/mindsdb?source=hncounter-feed) hackathon.

### Installation
Expand All @@ -26,92 +24,112 @@ pip install -U hey-mindsdb
pip install git+http://github.com/lnxpy/hey.git
```

> :warning:: Hey is POSIX-friendly. It might not work properly on the Windows machines at the moment.
> :warning:: Hey is POSIX-friendly. It might not work properly on Windows machines at the moment.

</details>

<details>
<summary><h4>2. Set the <code>MINDSDB_EMAIL_ADDRESS</code> environment variable</h4></summary>
<summary><h4>2. Set the <code>HEY_TOKEN</code> environment variable</h4></summary>

Once you got the package installed on your system, it's time to add the `MINDSDB_EMAIL_ADDRESS` environment variable. Create an account on [mindsdb.com](https://mindsdb.com/), train your GPT model and replace your email with `<EMAIL>` in the following options.
Once you got the package installed on your system, it's time to add the token that you just copied from [mdb.ai](https://mdb.ai) into either the `.bashrc` (or `.zshrc`) file.

##### > If you use the default bash shell
- If you use the default bash shell
```sh
echo "export MINDSDB_EMAIL_ADDRESS=<EMAIL>" >> ~/.bashrc
echo "export HEY_TOKEN=<TOKEN>" >> ~/.bashrc
```
##### > If you use ZSH
- If you use ZSH
```sh
echo "export MINDSDB_EMAIL_ADDRESS=<EMAIL>" >> ~/.zshrc
echo "export HEY_TOKEN=<TOKEN>" >> ~/.zshrc
```

> :bulb:: Read the article for more information about training your MindsDB model.

</details>

<details>
<summary><h4>3. Set your MindsDB account password</h4></summary>

Now, it's time to set your account's password. Simply run `hey` with the `--auth` option and enter your MindsDB account password.
### Usage
There are different commands and sub-commands implemented once you install `hey`. Check them out via the `--help` flag.

```sh
hey --auth
hey --help
```

You're all set to go. :)
```

Usage: hey [OPTIONS] COMMAND [ARGS]...

Hey is a pair-programming friend that interacts with ChatGPT and responds back in a pretty
style. ✨

╭─ Options ─────────────────────────────────────────────────────────────────────────────────────╮
│ --no-style,--ns Don't style the output. │
│ --version -V Show the current version of Hey. │
│ --install-completion Install completion for the current shell. │
│ --show-completion Show completion for the current shell, to copy it or │
│ customize the installation. │
│ --help Show this message and exit. │
╰───────────────────────────────────────────────────────────────────────────────────────────────╯
╭─ Commands ────────────────────────────────────────────────────────────────────────────────────╮
│ ask Ask Hey directly in-command. │
│ config Configuration management. │
╰───────────────────────────────────────────────────────────────────────────────────────────────╯
```

</details>
- If you want to use `Hey` in a fast and quick way, use the `ask` command.

### Usage
Use `hey` followed by your question and it'll process the phrase and responses back the content in Markdown.
```sh
hey ask "explain the duality term in quantum physics."
```

```
$ hey generate a power function in javascript
To generate a power function in JavaScript, you can use the built-in Math.pow()
method. Here's an example of how to create a power function using JavaScript:
- If your query needs more explanations with code snippets maybe, they just `hey`.

```sh
hey
<OPENS EDITOR>
```

function powerFunction(base, exponent) {
return Math.pow(base, exponent);
}
> Keep in mind that when you run `hey` with no sub-commands, the default `$EDITOR` will be used. Feel free to ask your question in markdown style.

// Example usage:
console.log(powerFunction(2, 3)); // Output: 8
console.log(powerFunction(5, 2)); // Output: 25
```
### Configuration
There is a command dedicated for more customizability. Check the following bullet-points.

```
$ hey tell me a programming joke
Why do programmers always mix up Christmas and Halloween?
- Create a base configuration file.

Because Oct 31 == Dec 25!
```
```sh
hey config create
```

```
$ hey add annotations to this function: $(cat file.py)
To add annotations to the given Python function, you can include comments and
docstrings to provide more information about the function's purpose and usage.
Here's an example:


# Importing the required module from setuptools package
from setuptools import setup

# Function to setup MindsDB package
def mindsdb_setup():
"""
This function sets up the MindsDB package using the setup() function from
setuptools.
"""
# Calling the setup() function to configure the package
setup()
- View and edit the configuration file.

```sh
hey config edit
```

Here is more information about each configuration parameter.

```json
{
// model version
"model": "gpt-3.5-turbo",

// prompt
"prompt": "Answer in a helpful way.",

// themes used for the codeblocks
"code_block_theme": "github-light",

// how would you like `hey` to think?
"loading_text": "Thinking..",

// thinking animation symbol
// check out full list: python -m rich.spinner
"loading_spinner": "dots",

// never style the output (in case you need to copy the result)
"never_style": false
}
```

### Tech Stack
- Tools
- [Python](https://python.org)
- Infrastructures & Hosting
- [MindsDB](https://mindsdb.com)
- [PyPI](https://pypi.org)
- [MindsDB](https://mdb.ai)

### Package Stats
![stats](media/stats.svg)
Expand Down
10 changes: 6 additions & 4 deletions hey/__init__.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
"""Top-level package for Hey."""
from rich.console import Console

__author__ = """Sadra Yahyapour"""
__email__ = '[email protected]'
__version__ = '0.2.0'
console = Console()

__author__ = "Sadra Yahyapour"
__email__ = "[email protected]"
__version__ = "0.3.0"
164 changes: 70 additions & 94 deletions hey/cli.py
Original file line number Diff line number Diff line change
@@ -1,100 +1,76 @@
import argparse
import os
import sys
from getpass import getpass

import keyring
from rich.console import Console

from hey import __version__
from hey.constants.informations import APPLICATION_DESCRIPTION
from hey.constants.informations import EPILOG_DESCRIPTION
from hey.constants.informations import INSTALLATION_GUIDE
from hey.constants.informations import VERSION_INFO
from hey.constants.service import KEYRING_SERVICE_NAME
from hey.constants.system import LOCAL_EMAIL_ADDRESS_VARIABLE_NAME
from hey.exceptions.system import BrokenCredentials
from hey.exceptions.system import EmailEnvVarNotExists
from hey.exceptions.system import KeyringIssue
from hey.middlewares.mindsdb import MindsDB

parser = argparse.ArgumentParser(
description=APPLICATION_DESCRIPTION + '\n\r\n\r' + INSTALLATION_GUIDE,
epilog=EPILOG_DESCRIPTION,
formatter_class=argparse.RawDescriptionHelpFormatter,
prog='hey',
)

parser.add_argument(
'ask',
nargs='*',
help='ask what you need',
)

parser.add_argument(
'--version',
action='version',
version=VERSION_INFO.format(__version__),
)

parser.add_argument(
'--auth',
action='store_true',
help='set your mindsdb account password',
)


def main():
args = parser.parse_args()
console = Console()

if args.auth:
email_address = os.environ.get(LOCAL_EMAIL_ADDRESS_VARIABLE_NAME)
password = getpass(f'Password for ({email_address}):')
if email_address:
try:
keyring.set_password(
service_name=KEYRING_SERVICE_NAME.lower(),
username=email_address,
password=password,
)
except Exception as _:
raise KeyringIssue(
'There is something wrong with your OS keyring system. Make sure you have right access to run hey '
'on your system. '
)
console.print(f'Password successfully set for {email_address}!')
else:
raise EmailEnvVarNotExists(f'Make sure you have defined {LOCAL_EMAIL_ADDRESS_VARIABLE_NAME} environment '
f'variable properly.')

credentials = keyring.get_credential(
service_name=KEYRING_SERVICE_NAME.lower(),
username=os.environ.get(LOCAL_EMAIL_ADDRESS_VARIABLE_NAME),
)

if not credentials:
raise BrokenCredentials(
f'Make sure you have set your {LOCAL_EMAIL_ADDRESS_VARIABLE_NAME} and password via --auth.'
from datetime import datetime
from typing import Annotated, Optional

import typer
from rich.markdown import Markdown
from rich.panel import Panel

from hey import __version__, console
from hey.configs import cli, configs
from hey.consts import APP_NAME
from hey.editor import open_tmp_editor
from hey.openai import answer

app = typer.Typer()
app.add_typer(cli.app, name="config")


def version_callback(value: bool):
if value:
print(f"Hey - {__version__}!")
raise typer.Exit()


@app.callback(invoke_without_command=True)
def main(
ctx: typer.Context,
no_style: Annotated[
bool, typer.Option("--no-style", "--ns", help="Don't style the output.")
] = configs.get("never_style"),
version: Annotated[
Optional[bool],
typer.Option(
"--version",
"-V",
callback=version_callback,
help=f"Show the current version of {APP_NAME}.",
),
] = None,
):
"""
Hey is a pair-programming friend that interacts with ChatGPT and responds back in a pretty style. ✨
"""

if ctx.invoked_subcommand is None:
user_input = open_tmp_editor()
markdown_input = Markdown(
user_input, code_theme=configs.get("code_block_theme")
)

if args.ask:
with console.status('Creating instance..'):
instance = MindsDB(
email=credentials.username,
password=credentials.password
)

with console.status('Authenticating..', spinner='dots2'):
instance.authenticate()
user_panel = Panel(
markdown_input,
title=":bust_in_silhouette:",
title_align="left",
subtitle=datetime.now().strftime("%H:%M"),
subtitle_align="right",
style="blue",
)

with console.status('Hey is typing..'):
console.print(instance.answer(
' '.join(args.ask)
))
console.print(user_panel)
result = answer(user_input, no_style)
console.print(result)

return 0

@app.command()
def ask(
user_input: str,
no_style: Annotated[
bool, typer.Option("--no-style", "--ns", help="Don't style the output.")
] = configs.get("never_style"),
):
"""
Ask Hey directly in-command.
"""

if __name__ == "__main__":
sys.exit(main())
result = answer(user_input, no_style)
console.print(result)
Loading
Loading