forked from poe-platform/server-bot-quick-start
-
Notifications
You must be signed in to change notification settings - Fork 14
/
Copy pathbot_CmdLine.py
116 lines (88 loc) · 3.02 KB
/
bot_CmdLine.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
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
"""
BOT_NAME="CmdLine"; modal deploy --name $BOT_NAME bot_${BOT_NAME}.py; curl -X POST https://api.poe.com/bot/fetch_settings/$BOT_NAME/$POE_ACCESS_KEY
Test message:
echo z > a.txt
cat a.txt
"""
from __future__ import annotations
import os
import re
import stat
from typing import AsyncIterable
import fastapi_poe as fp
import modal
from fastapi_poe import PoeBot, make_app
from fastapi_poe.types import PartialResponse, QueryRequest
from modal import App, Image, asgi_app
def extract_codes(reply):
pattern = r"```(bash|sh)\n([\s\S]*?)\n```"
matches = re.findall(pattern, reply)
if matches:
return matches
return []
image_exec = Image.debian_slim().apt_install("curl").apt_install("git")
class EchoBot(PoeBot):
async def get_response(
self, request: QueryRequest
) -> AsyncIterable[PartialResponse]:
for query in request.query[::-1]:
commands = extract_codes(query.content)
if commands:
break
else:
commands = [request.query[-1].content]
yield fp.MetaResponse(
text="",
content_type="text/markdown",
linkify=True,
refetch_settings=False,
suggested_replies=False,
)
print("check")
print(commands)
for command in commands:
nfs = modal.NetworkFileSystem.from_name(
f"vol-{request.user_id}", create_if_missing=True
)
filename = f"{request.conversation_id}.sh"
with open(f"{filename}", "w") as f:
f.write(command)
os.chmod(filename, os.stat(filename).st_mode | stat.S_IEXEC)
nfs.add_local_file(
f"{request.conversation_id}.sh", f"{request.conversation_id}.sh"
)
sb = app.spawn_sandbox(
"bash",
"-c",
f"cd /cache && {command}",
# f"cd /cache && chmod +x {filename} && ./{filename}",
network_file_systems={"/cache": nfs},
image=image_exec,
)
sb.wait()
output = sb.stdout.read()
error = sb.stderr.read()
nothing_returned = True
if output:
yield PartialResponse(text=f"""```output\n{output}\n```\n""")
nothing_returned = False
if output and error:
yield PartialResponse(text="""\n\n""")
if error:
yield PartialResponse(text=f"""```error\n{error}\n```\n""")
nothing_returned = False
if nothing_returned:
yield PartialResponse(text="""No output or error returned.""")
# specific to hosting with modal.com
image = (
Image.debian_slim()
.pip_install("fastapi-poe==0.0.45")
.env({"POE_ACCESS_KEY": os.environ["POE_ACCESS_KEY"]})
)
app = App("poe-bot-quickstart")
bot = EchoBot()
@app.function(image=image)
@asgi_app()
def fastapi_app():
app = make_app(bot, api_key=os.environ["POE_ACCESS_KEY"])
return app