Compare commits

...

2 Commits

5 changed files with 64 additions and 3 deletions

View File

@ -1,3 +1,49 @@
# LLM Chat # LLM Chat
A general CLI interface for large language models. This project is currently a CLI interface for OpenAI's [GPT model API](https://platform.openai.com/docs/guides/gpt). The long term goal is to be much more general and interface with any LLM, whether that be a cloud service or a model running locally.
## Usage
### Installation
The package is not currently published so you will need to build it yourself. To do so you will need [Poetry](https://python-poetry.org/) v1.5 or later. Once you have that installed, run the following commands:
```bash
git clone https://code.harrison.sh/paul/llm-chat.git
cd llm-chat
poetry build
```
This will create a wheel file in the `dist` directory. You can then install it with `pip`:
```bash
pip install dist/llm_chat-0.6.1-py3-none-any.whl
```
Note, a much better way to install this package system wide is to use [pipx](https://pypa.github.io/pipx/). This will install the package in an isolated environment and make the `llm` command available on your path.
### Configuration
Your OpenAI API key must be set in the `OPENAI_API_KEY` environment variable. The following additional environment variables are supported:
| Variable | Description |
| -------------------- | ------------------------------------------------------------------ |
| `OPENAI_MODEL` | The model to use. Defaults to `gpt-3.5-turbo`. |
| `OPENAI_TEMPERATURE` | The temperature to use when generating text. Defaults to `0.7`. |
| `OPENAI_HISTORY_DIR` | The directory to store chat history in. Defaults to `~/.llm_chat`. |
The settings can also be configured via command line arguments. Run `llm chat --help` for more information.
### Usage
To start a chat session, run the following command:
```bash
llm chat
```
This will start a chat session with the default settings looking something like the image below:
![Chat session](./llm-chat.png)
The CLI accepts multi-line input, so to send the input to the model press `Esc + Enter`. After each message a running total cost will be displayed. To exit the chat session, send the message `/q`.

BIN
llm-chat.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 99 KiB

View File

@ -1,6 +1,6 @@
[tool.poetry] [tool.poetry]
name = "llm-chat" name = "llm-chat"
version = "0.6.0" version = "0.6.1"
description = "A general CLI interface for large language models." description = "A general CLI interface for large language models."
authors = ["Paul Harrison <paul@harrison.sh>"] authors = ["Paul Harrison <paul@harrison.sh>"]
readme = "README.md" readme = "README.md"

View File

@ -1,6 +1,7 @@
from enum import StrEnum from enum import StrEnum
from pathlib import Path from pathlib import Path
from pydantic import field_validator
from pydantic_settings import BaseSettings, SettingsConfigDict from pydantic_settings import BaseSettings, SettingsConfigDict
@ -13,7 +14,7 @@ class Model(StrEnum):
DEFAULT_MODEL = Model.GPT3 DEFAULT_MODEL = Model.GPT3
DEFAULT_TEMPERATURE = 0.7 DEFAULT_TEMPERATURE = 0.7
DEFAULT_HISTORY_DIR = Path().absolute() / ".history" DEFAULT_HISTORY_DIR = Path.home() / ".llm_chat"
class OpenAISettings(BaseSettings): class OpenAISettings(BaseSettings):
@ -31,3 +32,10 @@ class OpenAISettings(BaseSettings):
frozen=True, frozen=True,
use_enum_values=True, use_enum_values=True,
) )
@field_validator("history_dir")
def history_dir_must_exist(cls, history_dir: Path) -> Path:
"""Ensure that the history directory exists."""
if not history_dir.exists():
history_dir.mkdir(parents=True)
return history_dir

View File

@ -1,4 +1,5 @@
import os import os
from pathlib import Path
import pytest import pytest
@ -7,3 +8,9 @@ import pytest
def mock_openai_api_key() -> None: def mock_openai_api_key() -> None:
"""Set a fake OpenAI API key.""" """Set a fake OpenAI API key."""
os.environ["OPENAI_API_KEY"] = "dummy_key" os.environ["OPENAI_API_KEY"] = "dummy_key"
@pytest.fixture(autouse=True)
def mock_history_dir(tmp_path: Path) -> None:
"""Set a fake history directory."""
os.environ["OPENAI_HISTORY_DIR"] = str(tmp_path / ".llm_chat")