Build a typing assistant with Ollama, Mistral 7B, and Python
I built a locally running typing assistant with Ollama, Mistral 7B, and Python. In this post, I'll show you how to do it.
It's a script with less than 100 lines of code that can run in the background and listen to hotkeys, then uses a Large Language Model to fix the text.
Inspired by this tweet:
https://twitter.com/karpathy/status/1725553780878647482
"GPT is surprisingly good at correcting minor typos, so you can write really really fast, ignore mistakes and keep going, and it comes out just fine." - Andrej Karpathy
The full code is on GitHub: https://github.com/patrickloeber/ai-typing-assistant
And here's a demo and a step-by-step coding tutorial if you prefer video content:
Project setup:
#Ollama Installation: https://github.com/ollama/ollama.
Run ollama run mistral:7b-instruct-v0.2-q4_K_S
.
I found that Mistal 7B Instruct (quantized) works well for this task, but feel free to try other models, too 😃
It relies on those dependencies:
- pynput: To listen to hotkeys and control the keyboard
- pyperclip: Clipboard functions to copy and paste text
- httpx: To send a POST request to Ollama running on your localhost
Install the dependencies with pip
:
pip install pynput pyperclip httpx
Everything should work cross-platform, only the shortcuts need to be adapted for your system.
Hotkey listener in Python
#This is how you can write a Hotkey listener with Python and pynput
:
from pynput import keyboard
def on_f9():
fix_current_line()
def on_f10():
fix_selection()
with keyboard.GlobalHotKeys({"<101>": on_f9, "<109>": on_f10}) as h:
h.join()
This runs endlessly in a separate thread until you stop the script.
Modify lines and selected text with Python
#To modify selected lines, we only need the functionality to copy and paste text (= Cmd+C
and Cmd+V
), and to access and modify the clipboard with Python. For this, set up a keyboard controller with pynput
, and use pyperclip
for the clipboard functions:
import time
from pynput.keyboard import Key, Controller
import pyperclip
controller = Controller()
def fix_current_line():
# macOS short cut to select current line: Cmd+Shift+Left
controller.press(Key.cmd)
controller.press(Key.shift)
controller.press(Key.left)
controller.release(Key.cmd)
controller.release(Key.shift)
controller.release(Key.left)
fix_selection()
def fix_selection():
# 1. Copy selection to clipboard
with controller.pressed(Key.cmd):
controller.tap("c")
# 2. Get the clipboard string
time.sleep(0.1)
text = pyperclip.paste()
# 3. Fix string
if not text:
return
fixed_text = fix_text(text)
if not fixed_text:
return
# 4. Paste the fixed string to the clipboard
pyperclip.copy(fixed_text)
time.sleep(0.1)
# 5. Paste the clipboard and replace the selected text
with controller.pressed(Key.cmd):
controller.tap("v")
Use Ollama and Mistral 7B to fix text
#Ollama comes with a REST API that's running on your localhost out of the box. So after the installation and downloading of the model, we only need to implement logic to send a POST request.
We also use a simple prompt that tells the model to fix all typos, casing, and punctuation:
import httpx
OLLAMA_ENDPOINT = "http://localhost:11434/api/generate"
OLLAMA_CONFIG = {
"model": "mistral:7b-instruct-v0.2-q4_K_S",
"keep_alive": "5m",
"stream": False,
}
PROMPT_TEMPLATE = Template(
"""Fix all typos and casing and punctuation in this text, but preserve all new line characters:
$text
Return only the corrected text, don't include a preamble.
"""
)
def fix_text(text):
prompt = PROMPT_TEMPLATE.substitute(text=text)
response = httpx.post(
OLLAMA_ENDPOINT,
json={"prompt": prompt, **OLLAMA_CONFIG},
headers={"Content-Type": "application/json"},
timeout=10,
)
if response.status_code != 200:
print("Error", response.status_code)
return None
return response.json()["response"].strip()
Run the typing assistant
#Put everything together and start the assistant:
python main.py
Hotkeys you can then press:
- F9: Fixes the current line (without having to select the text)
- F10: Fixes the current selection
Note: The code works on macOS. The underlying shortcuts in the code like Cmd+Shift+Left, Cmd+C, Cmd+V might have to be changed for Linux & Windows (e.g. Key.cmd
-> Key.ctrl
).
Customize
#The hotkeys, prompt, and Ollama config can be easily customized and extended in the code.
You can easily add hotkeys that summarize or generate new text.
For example, here are some fun other prompt templates you can try:
from string import Template
PROMPT_TEMPLATE_FIX_TEXT = Template(
"""Fix all typos and casing and punctuation in this text, but preserve all new line characters:
$text
Return only the corrected text."""
)
PROMPT_TEMPLATE_GENERATE_TEXT = Template(
"""Generate a snarky paragraph with 3 sentences about the following topic:
$text
Return only the corrected text."""
)
PROMPT_TEMPLATE_SUMMARIZE_TEXT = Template(
"""Summarize the following text in 3 sentences:
$text
Return only the corrected text."""
)
Have fun with it!
Hope you enjoyed the read!
▶ Follow me on
Twitter
&
LinkedIn
▶ Tutorials on
YouTube
▶ Dev Advocate at
AssemblyAI
▶ Founder of
python-engineer.com