Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 24 additions & 9 deletions interpreter/core/async_core.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@

import shortuuid
from pydantic import BaseModel
from starlette.websockets import WebSocketState
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No starlette in pyproject.toml

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.


from .core import OpenInterpreter

Expand Down Expand Up @@ -387,12 +388,14 @@ async def home():
async def websocket_endpoint(websocket: WebSocket):
await websocket.accept()

try:
try: # solving it ;)/ # killian super wrote this

async def receive_input():
authenticated = False
while True:
try:
if websocket.client_state != WebSocketState.CONNECTED:
return
data = await websocket.receive()

if not authenticated:
Expand Down Expand Up @@ -425,7 +428,7 @@ async def receive_input():
data = data["bytes"]
await async_interpreter.input(data)
elif data.get("type") == "websocket.disconnect":
print("Disconnecting.")
print("Client wants to disconnect, that's fine..")
return
else:
print("Invalid data:", data)
Expand All @@ -446,6 +449,8 @@ async def receive_input():

async def send_output():
while True:
if websocket.client_state != WebSocketState.CONNECTED:
return
try:
# First, try to send any unsent messages
while async_interpreter.unsent_messages:
Expand Down Expand Up @@ -488,9 +493,12 @@ async def send_message(output):
):
output["id"] = id

for attempt in range(100):
if websocket.client_state == 3: # 3 represents 'CLOSED' state
for attempt in range(20):
# time.sleep(0.5)

if websocket.client_state != WebSocketState.CONNECTED:
break

try:
if isinstance(output, bytes):
await websocket.send_bytes(output)
Expand All @@ -501,7 +509,7 @@ async def send_message(output):

if async_interpreter.require_acknowledge:
acknowledged = False
for _ in range(1000):
for _ in range(100):
if id in async_interpreter.acknowledged_outputs:
async_interpreter.acknowledged_outputs.remove(id)
acknowledged = True
Expand All @@ -523,10 +531,13 @@ async def send_message(output):
await asyncio.sleep(0.05)

# If we've reached this point, we've failed to send after 100 attempts
async_interpreter.unsent_messages.append(output)
print(
f"Added message to unsent_messages queue after failed attempts: {output}"
)
if output not in async_interpreter.unsent_messages:
async_interpreter.unsent_messages.append(output)
print(
f"Added message to unsent_messages queue after failed attempts: {output}"
)
else:
print("Why was this already in unsent_messages?", output)

await asyncio.gather(receive_input(), send_output())

Expand Down Expand Up @@ -731,6 +742,10 @@ def __init__(self, async_interpreter, host=None, port=None):
# Add authentication middleware
@self.app.middleware("http")
async def validate_api_key(request: Request, call_next):
# Ignore authentication for the /heartbeat route
if request.url.path == "/heartbeat":
return await call_next(request)

api_key = request.headers.get("X-API-KEY")
if self.authenticate(api_key):
response = await call_next(request)
Expand Down
25 changes: 25 additions & 0 deletions interpreter/core/respond.py
Original file line number Diff line number Diff line change
Expand Up @@ -181,6 +181,21 @@ def respond(interpreter):
except:
pass

if code.strip().endswith("executeexecute"):
edited_code = code.replace("executeexecute", "")
try:
code_dict = json.loads(edited_code)
language = code_dict.get("language", language)
code = code_dict.get("code", code)
interpreter.messages[-1][
"content"
] = code # So the LLM can see it.
interpreter.messages[-1][
"format"
] = language # So the LLM can see it.
except:
pass

if code.replace("\n", "").replace(" ", "").startswith('{"language":'):
try:
code_dict = json.loads(code)
Expand Down Expand Up @@ -247,6 +262,16 @@ def respond(interpreter):
else:
break

# Is there any code at all?
if code.strip() == "":
yield {
"role": "computer",
"type": "console",
"format": "output",
"content": "Code block was empty. Please try again, be sure to write code before executing.",
}
continue

# Yield a message, such that the user can stop code execution if they want to
try:
yield {
Expand Down
3 changes: 0 additions & 3 deletions numbers.txt

This file was deleted.

2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ packages = [
{include = "interpreter"},
{include = "scripts"},
]
version = "0.3.6" # Use "-rc1", "-rc2", etc. for pre-release versions
version = "0.3.7" # Use "-rc1", "-rc2", etc. for pre-release versions
description = "Let language models run code"
authors = ["Killian Lucas <[email protected]>"]
readme = "README.md"
Expand Down
Loading