forked from OpenInterpreter/open-interpreter
-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathview.py
94 lines (79 loc) · 3.43 KB
/
view.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
"""
This file contains the View class, which acts as our "frontend". It renders Open Interpreter's messages and code (but not code output, the rendering of which is handled by exec.py).
"""
from rich.console import Console
from rich.live import Live
from rich.panel import Panel
from rich.markdown import Markdown
from rich.syntax import Syntax
from rich.box import MINIMAL
import re
def textify_markdown_code_blocks(text):
replacement = "```text"
lines = text.split('\n')
inside_code_block = False
for i in range(len(lines)):
# If the line matches ``` followed by optional language specifier
if re.match(r'^```(\w*)$', lines[i].strip()):
inside_code_block = not inside_code_block
# If we just entered a code block, replace the marker
if inside_code_block:
lines[i] = replacement
return '\n'.join(lines)
class View:
def __init__(self):
self.console = Console()
self.live = None
self.current_type = None
self.current_content = ""
def process_delta(self, event):
try:
event_type = event["type"]
data = event["content"]
if event_type == 'message':
content = data
display_type = 'message'
elif event_type == 'function':
if 'code' in data:
content = data['code']
display_type = 'code'
else:
return
# elif 'name' in data:
# content = data['name']
# display_type = 'name'
# elif 'output' in data:
# content = data['output']
# display_type = 'output'
if (event_type, display_type) != self.current_type:
if display_type == 'code' and self.current_type == None:
# If it just became code after we just got here, print some whitespace
# (This is after user messages and other code blocks)
self.console.print("\n")
if self.live is not None:
self.live.stop()
self.live = Live(console=self.console, auto_refresh=False)
self.live.start()
self.current_type = (event_type, display_type)
self.current_content = content
else:
self.current_content += content
if display_type == 'message':
markdown = Markdown(textify_markdown_code_blocks(self.current_content))
current_display = Panel(markdown, box=MINIMAL)
elif display_type == 'code':
syntax = Syntax(self.current_content, "python", theme="monokai")
current_display = Panel(syntax, box=MINIMAL, style="on #272722")
# elif display_type == 'name':
# markdown = Markdown("# " + self.current_content)
# current_display = Panel(markdown, box=MINIMAL)
# elif display_type == 'output':
# current_display = Panel(self.current_content, box=MINIMAL, style=f"#FFFFFF on #3b3b37")
self.live.update(current_display, refresh=True)
except Exception as e:
# If an error occurs, stop the live display and raise the exception
self.finalize()
raise e
def finalize(self):
if self.live is not None:
self.live.stop()