DIY AI Typing Assistant using Phi-3 Mini and Python
This guide will show you how to build a lightweight AI typing assistant that runs locally on your Windows computer, helping you write faster and more accurately.
You’ll create a tool that runs in the background, ready to fix mistakes with a simple hotkey press. Press F9 to correct the current line or F10 to fix selected text. The assistant will correct typos, fix punctuation, and improve grammar. All of this without an internet connection, ensuring your data remains private.
Why We Chose phi3:mini
For this project, we’re using the phi3:mini model, a 3.8B parameter powerhouse that offers the perfect balance of efficiency and performance for our typing assistant. The model size is about 2.2GB.
- Superior Efficiency: At nearly half the size of models like Mistral 7B,
phi3:miniis significantly faster and more resource-efficient, ensuring quick response times without straining your computer. - Outstanding Performance: Despite its smaller size,
phi3:minidelivers near-GPT-3.5 quality for text correction tasks, outperforming many larger models on the Open LLM Leaderboard. - Hardware Friendly: It runs efficiently on standard office computers without requiring high-end GPUs, making it ideal for workplace deployment.
- Multilingual Support: Trained on diverse datasets, Phi-3 Mini is well-suited for text correction in multilingual environments.
What You’ll Build
You will create a Python script that:
- Runs in the background on your Windows machine.
- Listens for hotkeys (F9 and F10) to trigger text correction.
- Uses a local Ollama instance with
phi3:minito process and correct your text. - Supports language and style switching with additional hotkeys.
Step 1: Set Up Your Environment
1. Install Ollama:
- Download Ollama from ollama.com.
- Run the installer and follow the setup wizard.
- Open Command Prompt and run the following command to download the
phi3:minimodel (approximately 2.2GB):ollama run phi3:mini
2. Install Python Dependencies:
- Open Command Prompt and run:
pip install pynput pyperclip httpx
Step 2: Write the Code
Create a new file named typing_assistant.py and paste the following code into it. This script sets up the connection to Ollama, defines the prompt templates for text correction, and configures the keyboard listeners for the hotkeys.
import time
import httpx
from string import Template
from pynput import keyboard
from pynput.keyboard import Key, Controller
import pyperclip
# Initialize keyboard controller
controller = Controller()
# Ollama configuration
OLLAMA_ENDPOINT = "http://localhost:11434/api/generate"
OLLAMA_CONFIG = {
"model": "phi3:mini",
"keep_alive": "5m",
"stream": False,
}
# Language and style settings
current_language = "en" # Default: English
current_style = "standard" # Default: standard style
# Prompt templates for different languages and styles
PROMPT_TEMPLATES = {
"en": {
"standard": 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.
"""),
"formal": Template("""
Fix all typos, grammar, and punctuation in this text to
make it more formal and professional.
Preserve all new line characters:
$text
Return only the corrected text,
don't include a preamble.
"""),
"casual": Template("""
Fix all typos and punctuation in this text,
but keep a casual conversational tone.
Preserve all new line characters:
$text
Return only the corrected text,
don't include a preamble.
"""),
},
"de": {
"standard": Template("""
Korrigiere alle Tippfehler,
Großschreibung und Zeichensetzung in diesem Text,
aber behalte alle Zeilenumbrüche bei:
$text
Gib nur den korrigierten Text zurück,
ohne eine Einleitung.
"""),
"formal": Template("""
Korrigiere alle Tippfehler,
Grammatik und Zeichensetzung in diesem Text,
um es formeller und professioneller zu gestalten.
Behalte alle Zeilenumbrüche bei:
$text
Gib nur den korrigierten Text zurück,
ohne eine Einleitung.
"""),
"casual": Template("""
Korrigiere alle Tippfehler und Zeichensetzung
in diesem Text, aber behalte einen lockeren,
konversationellen Ton bei.
Behalte alle Zeilenumbrüche bei:
$text
Gib nur den korrigierten Text zurück,
ohne eine Einleitung.
"""),
},
}
def fix_text(text):
"""Send text to Ollama for correction"""
template = PROMPT_TEMPLATES[current_language][current_style]
prompt = template.substitute(text=text)
try:
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()
except Exception as e:
print("Error connecting to Ollama:", e)
return None
def fix_current_line():
"""Fix the current line using Ctrl+Shift+Home to select"""
# Select current line: Ctrl+Shift+Home
controller.press(Key.ctrl)
controller.press(Key.shift)
controller.press(Key.home)
controller.release(Key.ctrl)
controller.release(Key.shift)
controller.release(Key.home)
time.sleep(0.1)
fix_selection()
def fix_selection():
"""Fix the currently selected text"""
# Copy selection to clipboard
with controller.pressed(Key.ctrl):
controller.tap('c')
time.sleep(0.1)
text = pyperclip.paste()
if not text:
return
# Fix the text
fixed_text = fix_text(text)
if not fixed_text:
return
# Paste the fixed text
pyperclip.copy(fixed_text)
time.sleep(0.1)
with controller.pressed(Key.ctrl):
controller.tap('v')
def switch_to_english():
"""Switch language to English"""
global current_language
current_language = "en"
print("Switched to English")
def switch_to_german():
"""Switch language to German"""
global current_language
current_language = "de"
print("Zu Deutsch gewechselt")
def set_style_standard():
"""Set style to standard"""
global current_style
current_style = "standard"
print("Style set to standard")
def set_style_formal():
"""Set style to formal"""
global current_style
current_style = "formal"
print("Style set to formal")
def set_style_casual():
"""Set style to casual"""
global current_style
current_style = "casual"
print("Style set to casual")
def on_f9():
"""Handle F9 hotkey - fix current line"""
fix_current_line()
def on_f10():
"""Handle F10 hotkey - fix selection"""
fix_selection()
def show_status():
"""Display current language and style"""
lang_name = "English" if current_language == "en" else "German"
print(f"Current language: {lang_name}, Style: {current_style}")
if __name__ == "__main__":
print("AI Typing Assistant is running...")
print("Hotkeys:")
print(" F9: Fix current line")
print(" F10: Fix selection")
print(" Ctrl+F1: Switch to English")
print(" Ctrl+F2: Switch to German")
print(" Ctrl+F3: Set style to standard")
print(" Ctrl+F4: Set style to formal")
print(" Ctrl+F5: Set style to casual")
print(" Ctrl+F6: Show current status")
print("Press Ctrl+C in this window to exit")
# Set up hotkeys
with keyboard.GlobalHotKeys({
'<120>': on_f9, # F9
'<121>': on_f10, # F10
'<ctrl>+<f1>': switch_to_english,
'<ctrl>+<f2>': switch_to_german,
'<ctrl>+<f3>': set_style_standard,
'<ctrl>+<f4>': set_style_formal,
'<ctrl>+<f5>': set_style_casual,
'<ctrl>+<f6>': show_status,
}) as h:
h.join()
Step 3: Run and Test
- Open Command Prompt in the folder where you saved
typing_assistant.py. - Run the assistant:
python typing_assistant.py - Open any text editor (Notepad, Word, etc.) and start typing.
Test English Correction:
- Type:
Hello World, this is a test. - Press F9. The text should be corrected to:
Hello world this is a test
Test German Correction:
- Press Ctrl+F2 to switch to German.
- Type:
Hallo World, das ist ein test. - Press F9. The text should be corrected to:
Hallo Welt das ist ein Test
Troubleshooting
- Error connecting to Ollama: Ensure Ollama is running. You can check by running
ollama listin the Command Prompt. - Hotkeys don’t work: Try running the script as an administrator. Check if another program is using the same hotkeys.
- Slow corrections: The first correction might be slower as the model loads. Subsequent uses will be faster.
Congratulations! You’ve built a powerful AI typing assistant that will help you write more confidently and professionally.