Skip to content

Commit e17797f

Browse files
committed
feat: CLI history autosave
Implements a thread that auto saves history
1 parent d348a00 commit e17797f

File tree

2 files changed

+80
-26
lines changed

2 files changed

+80
-26
lines changed

interpreter/terminal_interface/terminal_interface.py

Lines changed: 3 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,6 @@
33
If you were to build a frontend this would be a way to do it.
44
"""
55

6-
try:
7-
import readline
8-
except ImportError:
9-
pass
10-
116
import os
127
import platform
138
import random
@@ -27,21 +22,7 @@
2722
from .utils.find_image_path import find_image_path
2823
from .utils.cli_input import cli_input
2924

30-
# Add examples to the readline history
31-
examples = [
32-
"How many files are on my desktop?",
33-
"What time is it in Seattle?",
34-
"Make me a simple Pomodoro app.",
35-
"Open Chrome and go to YouTube.",
36-
"Can you set my system to light mode?",
37-
]
38-
random.shuffle(examples)
39-
try:
40-
for example in examples:
41-
readline.add_history(example)
42-
except:
43-
# If they don't have readline, that's fine
44-
pass
25+
from .utils.history import history_autosaver
4526

4627

4728
def terminal_interface(interpreter, message):
@@ -72,18 +53,14 @@ def terminal_interface(interpreter, message):
7253
active_block = None
7354
voice_subprocess = None
7455

56+
history = history_autosaver() # Will stop when goes out of context
7557
while True:
7658
try:
7759
if interactive:
7860
### This is the primary input for Open Interpreter.
7961

80-
try:
81-
# This lets users hit the up arrow key for past messages
82-
readline.add_history(message)
83-
except:
84-
# If the user doesn't have readline (may be the case on windows), that's fine
85-
pass
8662
message = cli_input("> ", interpreter.multi_line).strip()
63+
history.add(message) # Maybe move this in cli_input?
8764

8865
except KeyboardInterrupt:
8966
# Exit gracefully
Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
import logging
2+
import os
3+
import queue
4+
import threading
5+
6+
from .oi_dir import oi_dir
7+
8+
log = logging.getLogger(__name__)
9+
10+
11+
# We probably want to decouple HistoryAutosave from oi_dir
12+
def history_autosaver(hist_filepath=os.path.join(oi_dir, "terminal.hist")):
13+
try:
14+
import readline
15+
16+
class HistoryAutosaver:
17+
# Messages queue
18+
_q: queue.Queue
19+
_thread: threading.Thread
20+
21+
def __init__(self):
22+
self._q = queue.Queue()
23+
self._run()
24+
25+
def add(self, msg, blocking=False):
26+
if blocking:
27+
readline.write_history_file(hist_filepath)
28+
else:
29+
self._q.put(msg)
30+
31+
def _load(self):
32+
try:
33+
readline.read_history_file(hist_filepath)
34+
except FileNotFoundError:
35+
pass
36+
37+
def _run(self):
38+
readline.set_auto_history(True) # Maybe redundant
39+
self._thread = threading.Thread(target=self._loop, daemon=True)
40+
self._thread.start()
41+
42+
def _loop(self):
43+
readline.read_history_file(hist_filepath)
44+
while True:
45+
log.debug("Waiting for history to write")
46+
msg = self._q.get()
47+
if msg is None:
48+
break
49+
try:
50+
readline.append_history_file(1, hist_filepath)
51+
except FileNotFoundError:
52+
readline.write_history_file(hist_filepath)
53+
log.debug("History written to " + hist_filepath)
54+
55+
def __del__(self):
56+
# Is this redundant?
57+
try:
58+
log.debug("Closing history manager")
59+
self._thread.join()
60+
except:
61+
pass
62+
63+
except ImportError:
64+
log.warning("readline module not found, history autosave disabled")
65+
66+
class HistoryAutosaver:
67+
pass
68+
69+
return HistoryAutosaver()
70+
71+
72+
if __name__ == "__main__":
73+
logging.basicConfig(level=logging.DEBUG)
74+
handle = history_autosaver()
75+
while True:
76+
cmd = input("")
77+
handle.add(cmd)

0 commit comments

Comments
 (0)