Skip to content

Commit 553a588

Browse files
authored
Updating main from development branch
Update
2 parents 4c24c34 + f304819 commit 553a588

File tree

7 files changed

+238
-218
lines changed

7 files changed

+238
-218
lines changed

interpreter/core/computer/calendar/calendar.py

Lines changed: 50 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -1,33 +1,38 @@
1-
import subprocess
2-
import platform
31
import datetime
4-
from ..utils.run_applescript import run_applescript_capture, run_applescript
2+
import platform
3+
import subprocess
4+
5+
from ..utils.run_applescript import run_applescript, run_applescript_capture
6+
57

68
class Calendar:
79
def __init__(self, computer):
810
self.computer = computer
911
# In the future, we might consider a way to use a different calender app. For now its Calendar
1012
self.calendar_app = "Calendar"
1113

12-
13-
14-
1514
def get_events(self, start_date=datetime.date.today(), end_date=None):
1615
"""
1716
Fetches calendar events for the given date or date range.
1817
"""
19-
if platform.system() != 'Darwin':
18+
if platform.system() != "Darwin":
2019
return "This method is only supported on MacOS"
2120

2221
# Format dates for AppleScript
23-
applescript_start_date = start_date.strftime('%A, %B %d, %Y') + " at 12:00:00 AM"
22+
applescript_start_date = (
23+
start_date.strftime("%A, %B %d, %Y") + " at 12:00:00 AM"
24+
)
2425
if end_date:
25-
applescript_end_date = end_date.strftime('%A, %B %d, %Y') + " at 11:59:59 PM"
26+
applescript_end_date = (
27+
end_date.strftime("%A, %B %d, %Y") + " at 11:59:59 PM"
28+
)
2629
else:
27-
applescript_end_date = start_date.strftime('%A, %B %d, %Y') + " at 11:59:59 PM"
28-
30+
applescript_end_date = (
31+
start_date.strftime("%A, %B %d, %Y") + " at 11:59:59 PM"
32+
)
33+
2934
# AppleScript command
30-
script = f'''
35+
script = f"""
3136
set theDate to date "{applescript_start_date}"
3237
set endDate to date "{applescript_end_date}"
3338
tell application "System Events"
@@ -135,7 +140,7 @@ def get_events(self, start_date=datetime.date.today(), end_date=None):
135140
return theString
136141
end listToString
137142
138-
'''
143+
"""
139144

140145
# Get outputs from AppleScript
141146
stdout, stderr = run_applescript_capture(script)
@@ -148,26 +153,32 @@ def get_events(self, start_date=datetime.date.today(), end_date=None):
148153

149154
return stdout
150155

151-
152-
153-
def create_event(self, title: str, start_date: datetime.datetime, end_date: datetime.datetime, location: str = "", notes: str = "", calendar: str = None) -> str:
156+
def create_event(
157+
self,
158+
title: str,
159+
start_date: datetime.datetime,
160+
end_date: datetime.datetime,
161+
location: str = "",
162+
notes: str = "",
163+
calendar: str = None,
164+
) -> str:
154165
"""
155166
Creates a new calendar event in the default calendar with the given parameters using AppleScript.
156167
"""
157-
if platform.system() != 'Darwin':
168+
if platform.system() != "Darwin":
158169
return "This method is only supported on MacOS"
159170

160171
# Format datetime for AppleScript
161-
applescript_start_date = start_date.strftime('%B %d, %Y %I:%M:%S %p')
162-
applescript_end_date = end_date.strftime('%B %d, %Y %I:%M:%S %p')
163-
172+
applescript_start_date = start_date.strftime("%B %d, %Y %I:%M:%S %p")
173+
applescript_end_date = end_date.strftime("%B %d, %Y %I:%M:%S %p")
174+
164175
# If there is no calendar, lets use the first calendar applescript returns. This should probably be modified in the future
165176
if calendar is None:
166177
calendar = self.get_first_calendar()
167178
if calendar is None:
168179
return "Can't find a default calendar. Please try again and specify a calendar name."
169-
170-
script = f'''
180+
181+
script = f"""
171182
-- Open and activate calendar first
172183
tell application "System Events"
173184
set calendarIsRunning to (name of processes) contains "{self.calendar_app}"
@@ -188,34 +199,33 @@ def create_event(self, title: str, start_date: datetime.datetime, end_date: date
188199
-- tell the Calendar app to refresh if it's running, so the new event shows up immediately
189200
tell application "{self.calendar_app}" to reload calendars
190201
end tell
191-
'''
192-
202+
"""
193203

194204
try:
195205
run_applescript(script)
196-
return f'''Event created successfully in the "{calendar}" calendar.'''
206+
return f"""Event created successfully in the "{calendar}" calendar."""
197207
except subprocess.CalledProcessError as e:
198208
return str(e)
199-
200-
201-
202-
def delete_event(self, event_title: str, start_date: datetime.datetime, calendar: str = None) -> str:
203-
if platform.system() != 'Darwin':
209+
210+
def delete_event(
211+
self, event_title: str, start_date: datetime.datetime, calendar: str = None
212+
) -> str:
213+
if platform.system() != "Darwin":
204214
return "This method is only supported on MacOS"
205-
215+
206216
# The applescript requires a title and start date to get the right event
207217
if event_title is None or start_date is None:
208218
return "Event title and start date are required"
209-
219+
210220
# If there is no calendar, lets use the first calendar applescript returns. This should probably be modified in the future
211221
if calendar is None:
212222
calendar = self.get_first_calendar()
213223
if not calendar:
214224
return "Can't find a default calendar. Please try again and specify a calendar name."
215-
225+
216226
# Format datetime for AppleScript
217-
applescript_start_date = start_date.strftime('%B %d, %Y %I:%M:%S %p')
218-
script = f'''
227+
applescript_start_date = start_date.strftime("%B %d, %Y %I:%M:%S %p")
228+
script = f"""
219229
-- Open and activate calendar first
220230
tell application "System Events"
221231
set calendarIsRunning to (name of processes) contains "{self.calendar_app}"
@@ -250,22 +260,20 @@ def delete_event(self, event_title: str, start_date: datetime.datetime, calenda
250260
return "Event deleted successfully."
251261
end if
252262
end tell
253-
'''
254-
263+
"""
264+
255265
stderr, stdout = run_applescript_capture(script)
256266
if stdout:
257267
return stdout[0].strip()
258268
elif stderr:
259269
if "successfully" in stderr:
260270
return stderr
261-
262-
return f'''Error deleting event: {stderr}'''
271+
272+
return f"""Error deleting event: {stderr}"""
263273
else:
264274
return "Unknown error deleting event. Please check event title and date."
265275

266-
267276
def get_first_calendar(self) -> str:
268-
269277
# Literally just gets the first calendar name of all the calendars on the system. AppleScript does not provide a way to get the "default" calendar
270278
script = f"""
271279
-- Open calendar first
@@ -286,4 +294,4 @@ def get_first_calendar(self) -> str:
286294
if stdout:
287295
return stdout[0].strip()
288296
else:
289-
return None
297+
return None

interpreter/core/computer/skills/skills.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -49,14 +49,14 @@ def create(self):
4949
"""
5050
@@@SEND_MESSAGE_AS_USER@@@
5151
INSTRUCTIONS
52-
You are creating a new skill. Follow these steps exactly:
52+
You are creating a new skill. Follow these steps exactly to get me to tell you its name:
5353
1. Ask me what the name of this skill is.
54-
2. When I respond, write the following (including the markdown code block):
54+
2. After I explicitly tell you the name of the skill (I may tell you to proceed which is not the name— if I do say that, you probably need more information from me, so tell me that), after you get the proper name, write the following (including the markdown code block):
5555
5656
---
5757
Got it. Give me one second.
5858
```python
59-
computer.skills.new_skill.name = "{my chosen skill name}"`.
59+
computer.skills.new_skill.name = "{INSERT THE SKILL NAME FROM QUESTION #1^}"`.
6060
```
6161
---
6262
Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,27 @@
11
import subprocess
22

3+
34
def run_applescript(script):
45
"""
56
Runs the given AppleScript using osascript and returns the result.
67
"""
7-
args = ['osascript', '-e', script]
8+
print("Running this AppleScript:\n", script)
9+
print(
10+
"---\nFeel free to directly run AppleScript to accomplish the user's task. This gives you more granular control than the `computer` module, but it is slower."
11+
)
12+
args = ["osascript", "-e", script]
813
return subprocess.check_output(args, universal_newlines=True)
914

1015

1116
def run_applescript_capture(script):
1217
"""
1318
Runs the given AppleScript using osascript, captures the output and error, and returns them.
1419
"""
15-
args = ['osascript', '-e', script]
20+
print("Running this AppleScript:\n", script)
21+
print(
22+
"---\nFeel free to directly run AppleScript to accomplish the user's task. This gives you more granular control than the `computer` module, but it is slower."
23+
)
24+
args = ["osascript", "-e", script]
1625
result = subprocess.run(args, capture_output=True, text=True, check=False)
1726
stdout, stderr = result.stdout, result.stderr
1827
return stdout, stderr

interpreter/core/core.py

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -49,9 +49,9 @@ def __init__(
4949
max_output=2800,
5050
safe_mode="off",
5151
shrink_images=False,
52-
loop=False,
53-
loop_message="""Proceed. You CAN run code on my machine. If you want to run code, start your message with "```"! If the entire task I asked for is done, say exactly 'The task is done.' If you need some specific information (like username or password) say EXACTLY 'Please provide more information.' If it's impossible, say 'The task is impossible.' (If I haven't provided a task, say exactly 'Let me know what you'd like to do next.') Otherwise keep going.""",
54-
loop_breakers=[
52+
force_task_completion=False,
53+
force_task_completion_message="""Proceed. You CAN run code on my machine. If you want to run code, start your message with "```"! If the entire task I asked for is done, say exactly 'The task is done.' If you need some specific information (like username or password) say EXACTLY 'Please provide more information.' If it's impossible, say 'The task is impossible.' (If I haven't provided a task, say exactly 'Let me know what you'd like to do next.') Otherwise keep going.""",
54+
force_task_completion_breakers=[
5555
"the task is done.",
5656
"the task is impossible.",
5757
"let me know what you'd like to do next.",
@@ -92,9 +92,9 @@ def __init__(
9292
self.multi_line = multi_line
9393

9494
# Loop messages
95-
self.loop = loop
96-
self.loop_message = loop_message
97-
self.loop_breakers = loop_breakers
95+
self.force_task_completion = force_task_completion
96+
self.force_task_completion_message = force_task_completion_message
97+
self.force_task_completion_breakers = force_task_completion_breakers
9898

9999
# Conversation history
100100
self.conversation_history = conversation_history

interpreter/core/respond.py

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ def respond(interpreter):
1515
"""
1616

1717
last_unsupported_code = ""
18-
insert_loop_message = False
18+
insert_force_task_completion_message = False
1919

2020
while True:
2121
## RENDER SYSTEM MESSAGE ##
@@ -51,17 +51,17 @@ def respond(interpreter):
5151
messages_for_llm = interpreter.messages.copy()
5252
messages_for_llm = [rendered_system_message] + messages_for_llm
5353

54-
if insert_loop_message:
54+
if insert_force_task_completion_message:
5555
messages_for_llm.append(
5656
{
5757
"role": "user",
5858
"type": "message",
59-
"content": loop_message,
59+
"content": force_task_completion_message,
6060
}
6161
)
6262
# Yield two newlines to seperate the LLMs reply from previous messages.
6363
yield {"role": "assistant", "type": "message", "content": "\n\n"}
64-
insert_loop_message = False
64+
insert_force_task_completion_message = False
6565

6666
### RUN THE LLM ###
6767

@@ -261,28 +261,28 @@ def respond(interpreter):
261261
## LOOP MESSAGE
262262
# This makes it utter specific phrases if it doesn't want to be told to "Proceed."
263263

264-
loop_message = interpreter.loop_message
264+
force_task_completion_message = interpreter.force_task_completion_message
265265
if interpreter.os:
266-
loop_message = loop_message.replace(
266+
force_task_completion_message = force_task_completion_message.replace(
267267
"If the entire task I asked for is done,",
268268
"If the entire task I asked for is done, take a screenshot to verify it's complete, or if you've already taken a screenshot and verified it's complete,",
269269
)
270-
loop_breakers = interpreter.loop_breakers
270+
force_task_completion_breakers = interpreter.force_task_completion_breakers
271271

272272
if (
273-
interpreter.loop
273+
interpreter.force_task_completion
274274
and interpreter.messages
275275
and interpreter.messages[-1].get("role", "").lower() == "assistant"
276276
and not any(
277277
task_status in interpreter.messages[-1].get("content", "")
278-
for task_status in loop_breakers
278+
for task_status in force_task_completion_breakers
279279
)
280280
):
281-
# Remove past loop_message messages
281+
# Remove past force_task_completion_message messages
282282
interpreter.messages = [
283283
message
284284
for message in interpreter.messages
285-
if message.get("content", "") != loop_message
285+
if message.get("content", "") != force_task_completion_message
286286
]
287287
# Combine adjacent assistant messages, so hopefully it learns to just keep going!
288288
combined_messages = []
@@ -299,8 +299,8 @@ def respond(interpreter):
299299
combined_messages.append(message)
300300
interpreter.messages = combined_messages
301301

302-
# Send model the loop_message:
303-
insert_loop_message = True
302+
# Send model the force_task_completion_message:
303+
insert_force_task_completion_message = True
304304

305305
continue
306306

interpreter/terminal_interface/profiles/defaults/01.py

Lines changed: 12 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,9 @@
1212
interpreter.llm.max_tokens = 4096
1313
interpreter.auto_run = True
1414

15-
interpreter.loop = True
16-
interpreter.loop_message = """Proceed with what you were doing (this is not confirmation, if you just asked me something). You CAN run code on my machine. If you want to run code, start your message with "```"! If the entire task is done, say exactly 'The task is done.' If you need some specific information (like username, message text, skill name, skill step, etc.) say EXACTLY 'Please provide more information.' If it's impossible, say 'The task is impossible.' (If I haven't provided a task, say exactly 'Let me know what you'd like to do next.') Otherwise keep going. CRITICAL: REMEMBER TO FOLLOW ALL PREVIOUS INSTRUCTIONS. If I'm teaching you something, remember to run the related `computer.skills.new_skill` function."""
17-
interpreter.loop_breakers = [
15+
interpreter.force_task_completion = True
16+
interpreter.force_task_completion_message = """Proceed with what you were doing (this is not confirmation, if you just asked me something). You CAN run code on my machine. If you want to run code, start your message with "```"! If the entire task is done, say exactly 'The task is done.' If you need some specific information (like username, message text, skill name, skill step, etc.) say EXACTLY 'Please provide more information.' If it's impossible, say 'The task is impossible.' (If I haven't provided a task, say exactly 'Let me know what you'd like to do next.') Otherwise keep going. CRITICAL: REMEMBER TO FOLLOW ALL PREVIOUS INSTRUCTIONS. If I'm teaching you something, remember to run the related `computer.skills.new_skill` function."""
17+
interpreter.force_task_completion_breakers = [
1818
"The task is done.",
1919
"The task is impossible.",
2020
"Let me know what you'd like to do next.",
@@ -64,24 +64,26 @@
6464
6565
# THE COMPUTER API
6666
67-
The `computer` module is ALREADY IMPORTED, and can be used for most tasks:
67+
The `computer` module is ALREADY IMPORTED, and can be used for some tasks:
6868
6969
```python
70-
computer.browser.search(query) # Google search results will be returned from this function as a string
70+
result_string = computer.browser.search(query) # Google search results will be returned from this function as a string
7171
computer.files.edit(path_to_file, original_text, replacement_text) # Edit a file
7272
computer.calendar.create_event(title="Meeting", start_date=datetime.datetime.now(), end=datetime.datetime.now() + datetime.timedelta(hours=1), notes="Note", location="") # Creates a calendar event
73-
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
73+
events_string = 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
7474
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
75-
computer.contacts.get_phone_number("John Doe")
76-
computer.contacts.get_email_address("John Doe")
75+
phone_string = computer.contacts.get_phone_number("John Doe")
76+
contact_string = computer.contacts.get_email_address("John Doe")
7777
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
78-
computer.mail.get(4, unread=True) # Returns the {number} of unread emails, or all emails if False is passed
79-
computer.mail.unread_count() # Returns the number of unread emails
78+
emails_string = computer.mail.get(4, unread=True) # Returns the {number} of unread emails, or all emails if False is passed
79+
unread_num = computer.mail.unread_count() # Returns the number of unread emails
8080
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
8181
```
8282
8383
Do not import the computer module, or any of its sub-modules. They are already imported.
8484
85+
DO NOT use the computer module for ALL tasks. Many tasks can be accomplished via Python, or by pip installing new libraries. Be creative!
86+
8587
# GUI CONTROL (RARE)
8688
8789
You are a computer controlling language model. You can control the user's GUI.

0 commit comments

Comments
 (0)