Skip to content

Commit 4a95794

Browse files
committed
Faster
1 parent 396fea6 commit 4a95794

File tree

10 files changed

+141
-115
lines changed

10 files changed

+141
-115
lines changed

interpreter/core/computer/computer.py

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,30 @@ def __init__(self, interpreter):
5757
self.interpreter.max_output
5858
) # Should mirror interpreter.max_output
5959

60+
self.system_message = """
61+
62+
# THE COMPUTER API
63+
64+
A python `computer` module is ALREADY IMPORTED, and can be used for many tasks:
65+
66+
```python
67+
computer.browser.search(query) # Google search results will be returned from this function as a string
68+
computer.files.edit(path_to_file, original_text, replacement_text) # Edit a file
69+
computer.calendar.create_event(title="Meeting", start_date=datetime.datetime.now(), end_date=datetime.datetime.now() + datetime.timedelta(hours=1), notes="Note", location="") # Creates a calendar event
70+
computer.calendar.get_events(start_date=datetime.date.today(), end_date=None) # Get events between dates. If end_date is None, only gets events for start_date
71+
computer.calendar.delete_event(event_title="Meeting", start_date=datetime.datetime) # Delete a specific event with a matching title and start date, you may need to get use get_events() to find the specific event object first
72+
computer.contacts.get_phone_number("John Doe")
73+
computer.contacts.get_email_address("John Doe")
74+
computer.mail.send("[email protected]", "Meeting Reminder", "Reminder that our meeting is at 3pm today.", ["path/to/attachment.pdf", "path/to/attachment2.pdf"]) # Send an email with a optional attachments
75+
computer.mail.get(4, unread=True) # Returns the [number] of unread emails, or all emails if False is passed
76+
computer.mail.unread_count() # Returns the number of unread emails
77+
computer.sms.send("555-123-4567", "Hello from the computer!") # Send a text message. MUST be a phone number, so use computer.contacts.get_phone_number frequently here
78+
```
79+
80+
Do not import the computer module, or any of its sub-modules. They are already imported.
81+
82+
""".strip()
83+
6084
# Shortcut for computer.terminal.languages
6185
@property
6286
def languages(self):
Lines changed: 6 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -1,45 +1,19 @@
1-
default_system_message = r"""
1+
import getpass
2+
import platform
3+
4+
default_system_message = f"""
25
36
You are Open Interpreter, a world-class programmer that can complete any goal by executing code.
47
First, write a plan. **Always recap the plan between each code block** (you have extreme short-term memory loss, so you need to recap the plan between each message block to retain it).
58
When you execute code, it will be executed **on the user's machine**. The user has given you **full and complete permission** to execute any code necessary to complete the task. Execute the code.
6-
If you want to send data between programming languages, save the data to a txt or json.
79
You can access the internet. Run **any code** to achieve the goal, and if at first you don't succeed, try again and again.
810
You can install new packages.
911
When a user refers to a filename, they're likely referring to an existing file in the directory you're currently executing code in.
1012
Write messages to the user in Markdown.
1113
In general, try to **make plans** with as few steps as possible. As for actually executing code to carry out that plan, for *stateful* languages (like python, javascript, shell, but NOT for html which starts from 0 every time) **it's critical not to try to do everything in one code block.** You should try something, print information about it, then continue from there in tiny, informed steps. You will never get it on the first try, and attempting it in one go will often lead to errors you cant see.
1214
You are capable of **any** task.
1315
14-
# THE COMPUTER API
15-
16-
A python `computer` module is ALREADY IMPORTED, and can be used for many tasks:
17-
18-
```python
19-
computer.browser.search(query) # Google search results will be returned from this function as a string
20-
computer.files.edit(path_to_file, original_text, replacement_text) # Edit a file
21-
computer.calendar.create_event(title="Meeting", start_date=datetime.datetime.now(), end_date=datetime.datetime.now() + datetime.timedelta(hours=1), notes="Note", location="") # Creates a calendar event
22-
computer.calendar.get_events(start_date=datetime.date.today(), end_date=None) # Get events between dates. If end_date is None, only gets events for start_date
23-
computer.calendar.delete_event(event_title="Meeting", start_date=datetime.datetime) # Delete a specific event with a matching title and start date, you may need to get use get_events() to find the specific event object first
24-
computer.contacts.get_phone_number("John Doe")
25-
computer.contacts.get_email_address("John Doe")
26-
computer.mail.send("[email protected]", "Meeting Reminder", "Reminder that our meeting is at 3pm today.", ["path/to/attachment.pdf", "path/to/attachment2.pdf"]) # Send an email with a optional attachments
27-
computer.mail.get(4, unread=True) # Returns the {number} of unread emails, or all emails if False is passed
28-
computer.mail.unread_count() # Returns the number of unread emails
29-
computer.sms.send("555-123-4567", "Hello from the computer!") # Send a text message. MUST be a phone number, so use computer.contacts.get_phone_number frequently here
30-
```
31-
32-
Do not import the computer module, or any of its sub-modules. They are already imported.
33-
34-
User Info{{import getpass
35-
import os
36-
import platform
37-
38-
print(f"Name: {getpass.getuser()}")
39-
print(f"CWD: {os.getcwd()}")
40-
print(f"SHELL: {os.environ.get('SHELL')}")
41-
print(f"OS: {platform.system()}")
42-
43-
}}
16+
User's Name: {getpass.getuser()}
17+
User's OS: {platform.system()}
4418
4519
""".strip()

interpreter/core/llm/llm.py

Lines changed: 29 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,9 @@
11
import litellm
2+
3+
litellm.suppress_debug_info = True
4+
import time
5+
import uuid
6+
27
import tokentrim as tt
38

49
from ...terminal_interface.utils.display_markdown_message import (
@@ -8,9 +13,6 @@
813
from .run_text_llm import run_text_llm
914
from .utils.convert_to_openai_messages import convert_to_openai_messages
1015

11-
litellm.suppress_debug_info = True
12-
import time
13-
1416

1517
class Llm:
1618
"""
@@ -64,10 +66,20 @@ def run(self, messages):
6466
msg["role"] != "system"
6567
), "No message after the first can have the role 'system'"
6668

69+
model = self.model
70+
# Setup our model endpoint
71+
if model == "i":
72+
model = "openai/i"
73+
if not hasattr(self.interpreter, "conversation_id"): # Only do this once
74+
self.context_window = 7000
75+
self.max_tokens = 1000
76+
self.api_base = "https://api.openinterpreter.com/v0"
77+
self.interpreter.conversation_id = str(uuid.uuid4())
78+
6779
# Detect function support
6880
if self.supports_functions == None:
6981
try:
70-
if litellm.supports_function_calling(self.model):
82+
if litellm.supports_function_calling(model):
7183
self.supports_functions = True
7284
else:
7385
self.supports_functions = False
@@ -77,20 +89,13 @@ def run(self, messages):
7789
# Detect vision support
7890
if self.supports_vision == None:
7991
try:
80-
if litellm.supports_vision(self.model):
92+
if litellm.supports_vision(model):
8193
self.supports_vision = True
8294
else:
8395
self.supports_vision = False
8496
except:
8597
self.supports_vision = False
8698

87-
# Setup our model endpoint
88-
if self.model == "i":
89-
self.model = "openai/i"
90-
self.context_window = 7000
91-
self.max_tokens = 1000
92-
self.api_base = "https://api.openinterpreter.com/v0"
93-
9499
# Trim image messages if they're there
95100
image_messages = [msg for msg in messages if msg["type"] == "image"]
96101
if self.supports_vision:
@@ -154,7 +159,7 @@ def run(self, messages):
154159
else:
155160
try:
156161
messages = tt.trim(
157-
messages, system_message=system_message, model=self.model
162+
messages, system_message=system_message, model=model
158163
)
159164
except:
160165
if len(messages) == 1:
@@ -196,7 +201,7 @@ def run(self, messages):
196201
## Start forming the request
197202

198203
params = {
199-
"model": self.model,
204+
"model": model,
200205
"messages": messages,
201206
"stream": True,
202207
}
@@ -212,6 +217,8 @@ def run(self, messages):
212217
params["max_tokens"] = self.max_tokens
213218
if self.temperature:
214219
params["temperature"] = self.temperature
220+
if hasattr(self.interpreter, "conversation_id"):
221+
params["conversation_id"] = self.interpreter.conversation_id
215222

216223
# Set some params directly on LiteLLM
217224
if self.max_budget:
@@ -243,9 +250,16 @@ def fixed_litellm_completions(**params):
243250
"""
244251

245252
if "local" in params.get("model"):
246-
# Kinda hacky, but this helps
253+
# Kinda hacky, but this helps sometimes
247254
params["stop"] = ["<|assistant|>", "<|end|>", "<|eot_id|>"]
248255

256+
if params.get("model") == "i" and "conversation_id" in params:
257+
litellm.drop_params = (
258+
False # If we don't do this, litellm will drop this param!
259+
)
260+
else:
261+
litellm.drop_params = True
262+
249263
# Run completion
250264
first_error = None
251265
try:

interpreter/core/respond.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,13 @@ def respond(interpreter):
3131
if interpreter.custom_instructions:
3232
system_message += "\n\n" + interpreter.custom_instructions
3333

34+
# Add computer API system message
35+
if interpreter.computer.import_computer_api:
36+
if interpreter.computer.system_message not in system_message:
37+
system_message = (
38+
system_message + "\n\n" + interpreter.computer.system_message
39+
)
40+
3441
# Storing the messages so they're accessible in the interpreter's computer
3542
if interpreter.sync_computer:
3643
output = interpreter.computer.run(

interpreter/core/utils/telemetry.py

Lines changed: 12 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -10,17 +10,14 @@
1010
"""
1111

1212
import contextlib
13+
import json
1314
import os
15+
import threading
1416
import uuid
1517

1618
import pkg_resources
17-
from posthog import Posthog
1819
import requests
1920

20-
posthog = Posthog(
21-
"phc_6cmXy4MEbLfNGezqGjuUTY8abLu0sAwtGzZFpQW97lc", host="https://app.posthog.com"
22-
)
23-
2421

2522
def get_or_create_uuid():
2623
try:
@@ -49,17 +46,23 @@ def get_or_create_uuid():
4946

5047
def send_telemetry(event_name, properties=None):
5148
try:
52-
if properties == None:
49+
if properties is None:
5350
properties = {}
5451
properties["oi_version"] = pkg_resources.get_distribution(
5552
"open-interpreter"
5653
).version
5754
with open(os.devnull, "w") as f, contextlib.redirect_stdout(
5855
f
5956
), contextlib.redirect_stderr(f):
60-
posthog.capture(user_id, event_name, properties)
57+
url = "https://app.posthog.com/capture"
58+
headers = {"Content-Type": "application/json"}
59+
data = {
60+
"api_key": "phc_6cmXy4MEbLfNGezqGjuUTY8abLu0sAwtGzZFpQW97lc",
61+
"event": event_name,
62+
"properties": properties,
63+
"distinct_id": user_id,
64+
}
65+
response = requests.post(url, headers=headers, data=json.dumps(data))
6166
except:
6267
# Non blocking
6368
pass
64-
65-

interpreter/terminal_interface/contributing_conversations.py

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -46,8 +46,9 @@ def send_past_conversations(interpreter):
4646
"We are about to send all previous conversations to Open Interpreter for training an open-source language model. Please make sure these don't contain any private information. Run `interpreter --conversations` to browse them."
4747
)
4848
print()
49+
time.sleep(2)
4950
uh = input(
50-
"Do we have your permission to send all previous conversations to Open Interpreter? y/n"
51+
"Do we have your permission to send all previous conversations to Open Interpreter? (y/n): "
5152
)
5253
print()
5354
if uh == "y":
@@ -165,14 +166,21 @@ def is_list_of_lists(l):
165166
return isinstance(l, list) and all([isinstance(e, list) for e in l])
166167

167168

168-
def contribute_conversations(conversations: List[List]):
169+
def contribute_conversations(
170+
conversations: List[List], feedback=None, conversation_id=None
171+
):
169172
if len(conversations) == 0 or len(conversations[0]) == 0:
170173
return None
171174

172-
url = "https://api.openinterpreter.com/v0/conversations/contribute/"
175+
url = "https://api.openinterpreter.com/v0/contribute/"
173176
version = pkg_resources.get_distribution("open-interpreter").version
174177

175-
payload = {"conversations": conversations, "oi_version": version}
178+
payload = {
179+
"conversation_id": conversation_id,
180+
"conversations": conversations,
181+
"oi_version": version,
182+
"feedback": feedback,
183+
}
176184

177185
assert is_list_of_lists(
178186
payload["conversations"]

interpreter/terminal_interface/start_terminal_interface.py

Lines changed: 41 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -499,7 +499,44 @@ def main():
499499
except KeyboardInterrupt:
500500
pass
501501
finally:
502-
if interpreter.will_contribute:
503-
contribute_conversations([interpreter.messages])
504-
print("Thank you for contributing to our training data!")
505-
interpreter.computer.terminate()
502+
try:
503+
interpreter.computer.terminate()
504+
505+
if not interpreter.offline and not interpreter.disable_telemetry:
506+
feedback = None
507+
if len(interpreter.messages) > 3:
508+
feedback = (
509+
input("\n\nWas Open Interpreter helpful? (y/n): ")
510+
.strip()
511+
.lower()
512+
)
513+
if feedback == "y":
514+
feedback = True
515+
elif feedback == "n":
516+
feedback = False
517+
else:
518+
feedback = None
519+
if feedback != None and not interpreter.contribute_conversation:
520+
contribute = (
521+
input(
522+
"\nThanks for your feedback! Would you like to send us this chat so we can improve? (y/n): "
523+
)
524+
.strip()
525+
.lower()
526+
)
527+
if contribute == "y":
528+
interpreter.contribute_conversation = True
529+
print("Thank you for contributing!")
530+
531+
if interpreter.contribute_conversation and interpreter.messages != []:
532+
conversation_id = (
533+
interpreter.conversation_id
534+
if hasattr(interpreter, "conversation_id")
535+
else None
536+
)
537+
contribute_conversations(
538+
[interpreter.messages], feedback, conversation_id
539+
)
540+
541+
except KeyboardInterrupt:
542+
pass

interpreter/terminal_interface/validate_llm_settings.py

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,12 @@ def validate_llm_settings(interpreter):
3232
# Ensure API keys are set as environment variables
3333

3434
# OpenAI
35-
if interpreter.llm.model in litellm.open_ai_chat_completion_models:
35+
if interpreter.llm.model in [
36+
"gpt-4",
37+
"gpt-3.5-turbo",
38+
"gpt-40",
39+
"gpt-4-turbo",
40+
]:
3641
if (
3742
not os.environ.get("OPENAI_API_KEY")
3843
and not interpreter.llm.api_key

0 commit comments

Comments
 (0)