Skip to content

Commit de800d4

Browse files
committed
15 second terminal stdin patience
1 parent cf36dc5 commit de800d4

File tree

1 file changed

+55
-1
lines changed

1 file changed

+55
-1
lines changed

interpreter/core/computer/terminal/languages/jupyter_language.py

Lines changed: 55 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@
1313
import time
1414
import traceback
1515

16+
os.environ["LITELLM_LOCAL_MODEL_COST_MAP"] = "True"
17+
import litellm
1618
from jupyter_client import KernelManager
1719

1820
from ..base_language import BaseLanguage
@@ -88,6 +90,9 @@ def run(self, code):
8890
while not self.kc.is_alive():
8991
time.sleep(0.1)
9092

93+
self.last_output_time = time.time()
94+
self.last_output_message_time = time.time()
95+
9196
################################################################
9297
### OFFICIAL OPEN INTERPRETER GOVERNMENT ISSUE SKILL LIBRARY ###
9398
################################################################
@@ -144,7 +149,52 @@ def iopub_message_listener():
144149
self.finish_flag = True
145150
return
146151
try:
152+
if (
153+
time.time() - self.last_output_time > 15
154+
and time.time() - self.last_output_message_time > 15
155+
):
156+
self.last_output_message_time = time.time()
157+
158+
text = f"{self.computer.interpreter.messages}\n\nThe program above has been running for over 15 seconds. It might require user input. Are there keystrokes that the user should type in, to proceed after the last command?"
159+
if time.time() - self.last_output_time > 500:
160+
text += f" If you think the process is frozen, or that the user wasn't expect it to run for this long (it has been {time.time() - self.last_output_time} seconds since last output) then say <input>CTRL-C</input>."
161+
162+
messages = [
163+
{
164+
"role": "system",
165+
"type": "message",
166+
"content": "You are an expert programming assistant. You will help the user determine if they should enter input into the terminal, per the user's requests. If you think the user would want you to type something into stdin, enclose it in <input></input> XML tags, like <input>y</input> to type 'y'.",
167+
},
168+
{"role": "user", "type": "message", "content": text},
169+
]
170+
params = {
171+
"messages": messages,
172+
"model": self.computer.interpreter.llm.model,
173+
"stream": True,
174+
"temperature": 0,
175+
}
176+
if self.computer.interpreter.llm.api_key:
177+
params["api_key"] = self.computer.interpreter.llm.api_key
178+
179+
response = ""
180+
for chunk in litellm.completion(**params):
181+
content = chunk.choices[0].delta.content
182+
if type(content) == str:
183+
response += content
184+
185+
# Parse the response for input tags
186+
input_match = re.search(r"<input>(.*?)</input>", response)
187+
if input_match:
188+
user_input = input_match.group(1)
189+
# Check if the user input is CTRL-C
190+
self.finish_flag = True
191+
if user_input.upper() == "CTRL-C":
192+
self.finish_flag = True
193+
else:
194+
self.kc.input(user_input)
195+
147196
msg = self.kc.iopub_channel.get_msg(timeout=0.05)
197+
self.last_output_time = time.time()
148198
except queue.Empty:
149199
continue
150200
except Exception as e:
@@ -255,7 +305,10 @@ def detect_active_line(self, line):
255305
# Split the line by "##active_line" and grab the last element
256306
last_active_line = line.split("##active_line")[-1]
257307
# Split the last active line by "##" and grab the first element
258-
active_line = int(last_active_line.split("##")[0])
308+
try:
309+
active_line = int(last_active_line.split("##")[0])
310+
except:
311+
active_line = 0
259312
# Remove all ##active_line{number}##\n
260313
line = re.sub(r"##active_line\d+##\n", "", line)
261314
return line, active_line
@@ -279,6 +332,7 @@ def _capture_output(self, message_queue):
279332
if DEBUG_MODE:
280333
print(output)
281334
yield output
335+
282336
except queue.Empty:
283337
if self.finish_flag:
284338
time.sleep(0.1)

0 commit comments

Comments
 (0)