shenchucheng
commited on
Commit
·
d0921c0
1
Parent(s):
faf9dc6
add local storage
Browse files- .dockerignore +2 -1
- .gitignore +1 -0
- app.py +62 -54
- config/config.yaml +14 -0
- software_company.py +26 -17
.dockerignore
CHANGED
|
@@ -5,4 +5,5 @@ workspace
|
|
| 5 |
dist
|
| 6 |
data
|
| 7 |
geckodriver.log
|
| 8 |
-
logs
|
|
|
|
|
|
| 5 |
dist
|
| 6 |
data
|
| 7 |
geckodriver.log
|
| 8 |
+
logs
|
| 9 |
+
storage
|
.gitignore
CHANGED
|
@@ -169,3 +169,4 @@ output.wav
|
|
| 169 |
output
|
| 170 |
tmp.png
|
| 171 |
|
|
|
|
|
|
| 169 |
output
|
| 170 |
tmp.png
|
| 171 |
|
| 172 |
+
storage/*
|
app.py
CHANGED
|
@@ -6,6 +6,7 @@ import asyncio
|
|
| 6 |
from collections import deque
|
| 7 |
import contextlib
|
| 8 |
from functools import partial
|
|
|
|
| 9 |
import urllib.parse
|
| 10 |
from datetime import datetime
|
| 11 |
import uuid
|
|
@@ -154,58 +155,60 @@ async def create_message(req_model: NewMsg, request: Request):
|
|
| 154 |
"""
|
| 155 |
Session message stream
|
| 156 |
"""
|
| 157 |
-
|
| 158 |
-
|
| 159 |
-
|
| 160 |
-
|
| 161 |
-
|
| 162 |
-
|
| 163 |
-
|
| 164 |
-
|
| 165 |
-
|
| 166 |
-
|
| 167 |
-
|
| 168 |
-
|
| 169 |
-
|
| 170 |
-
|
| 171 |
-
|
| 172 |
-
|
| 173 |
-
|
| 174 |
-
|
| 175 |
-
|
| 176 |
-
|
| 177 |
-
|
| 178 |
-
|
| 179 |
-
|
| 180 |
-
|
| 181 |
-
|
| 182 |
-
|
| 183 |
-
|
| 184 |
-
|
| 185 |
-
|
| 186 |
-
|
| 187 |
-
think_act_prompt = ThinkActPrompt(role=think_result.role.profile)
|
| 188 |
-
think_act_prompt.update_think(tc_id, think_result)
|
| 189 |
-
yield think_act_prompt.prompt + "\n\n"
|
| 190 |
-
task = asyncio.create_task(role.act())
|
| 191 |
-
|
| 192 |
-
while not await request.is_disconnected():
|
| 193 |
-
if msg_queue:
|
| 194 |
-
think_act_prompt.update_act(msg_queue.pop(), False)
|
| 195 |
-
yield think_act_prompt.prompt + "\n\n"
|
| 196 |
-
continue
|
| 197 |
-
|
| 198 |
-
if task.done():
|
| 199 |
break
|
| 200 |
|
| 201 |
-
|
|
|
|
|
|
|
|
|
|
| 202 |
|
| 203 |
-
|
| 204 |
-
|
| 205 |
-
|
| 206 |
-
|
| 207 |
-
|
| 208 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 209 |
|
| 210 |
default_llm_stream_log = partial(print, end="")
|
| 211 |
|
|
@@ -236,10 +239,11 @@ class ChatHandler:
|
|
| 236 |
app = FastAPI()
|
| 237 |
|
| 238 |
app.mount(
|
| 239 |
-
"/
|
| 240 |
-
StaticFiles(directory="./
|
| 241 |
name="static",
|
| 242 |
)
|
|
|
|
| 243 |
app.add_api_route(
|
| 244 |
"/api/messages",
|
| 245 |
endpoint=ChatHandler.create_message,
|
|
@@ -250,13 +254,17 @@ app.add_api_route(
|
|
| 250 |
|
| 251 |
@app.get("/{catch_all:path}")
|
| 252 |
async def catch_all(request: Request):
|
| 253 |
-
if request.url.path == "/":
|
| 254 |
-
return RedirectResponse(url="/static/index.html")
|
| 255 |
if request.url.path.startswith("/api"):
|
| 256 |
raise HTTPException(status_code=404)
|
| 257 |
|
| 258 |
-
|
| 259 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 260 |
|
| 261 |
|
| 262 |
set_llm_stream_logfunc(llm_stream_log)
|
|
|
|
| 6 |
from collections import deque
|
| 7 |
import contextlib
|
| 8 |
from functools import partial
|
| 9 |
+
import shutil
|
| 10 |
import urllib.parse
|
| 11 |
from datetime import datetime
|
| 12 |
import uuid
|
|
|
|
| 155 |
"""
|
| 156 |
Session message stream
|
| 157 |
"""
|
| 158 |
+
try:
|
| 159 |
+
config = {k.upper(): v for k, v in req_model.config.items()}
|
| 160 |
+
set_context(config, uuid.uuid4().hex)
|
| 161 |
+
|
| 162 |
+
msg_queue = deque()
|
| 163 |
+
CONFIG.LLM_STREAM_LOG = lambda x: msg_queue.appendleft(x) if x else None
|
| 164 |
+
|
| 165 |
+
role = SoftwareCompany()
|
| 166 |
+
role.recv(message=Message(content=req_model.query))
|
| 167 |
+
answer = MessageJsonModel(
|
| 168 |
+
steps=[
|
| 169 |
+
Sentences(
|
| 170 |
+
contents=[
|
| 171 |
+
Sentence(type=SentenceType.TEXT.value, value=SentenceValue(answer=req_model.query), is_finished=True)
|
| 172 |
+
],
|
| 173 |
+
status=MessageStatus.COMPLETE.value,
|
| 174 |
+
)
|
| 175 |
+
],
|
| 176 |
+
qa_type=QueryAnswerType.Answer.value,
|
| 177 |
+
)
|
| 178 |
+
|
| 179 |
+
tc_id = 0
|
| 180 |
+
|
| 181 |
+
while True:
|
| 182 |
+
tc_id += 1
|
| 183 |
+
if request and await request.is_disconnected():
|
| 184 |
+
return
|
| 185 |
+
think_result: RoleRun = await role.think()
|
| 186 |
+
if not think_result: # End of conversion
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 187 |
break
|
| 188 |
|
| 189 |
+
think_act_prompt = ThinkActPrompt(role=think_result.role.profile)
|
| 190 |
+
think_act_prompt.update_think(tc_id, think_result)
|
| 191 |
+
yield think_act_prompt.prompt + "\n\n"
|
| 192 |
+
task = asyncio.create_task(role.act())
|
| 193 |
|
| 194 |
+
while not await request.is_disconnected():
|
| 195 |
+
if msg_queue:
|
| 196 |
+
think_act_prompt.update_act(msg_queue.pop(), False)
|
| 197 |
+
yield think_act_prompt.prompt + "\n\n"
|
| 198 |
+
continue
|
| 199 |
|
| 200 |
+
if task.done():
|
| 201 |
+
break
|
| 202 |
+
|
| 203 |
+
await asyncio.sleep(0.5)
|
| 204 |
+
|
| 205 |
+
act_result = await task
|
| 206 |
+
think_act_prompt.update_act(act_result)
|
| 207 |
+
yield think_act_prompt.prompt + "\n\n"
|
| 208 |
+
answer.add_think_act(think_act_prompt)
|
| 209 |
+
yield answer.prompt + "\n\n" # Notify the front-end that the message is complete.
|
| 210 |
+
finally:
|
| 211 |
+
shutil.rmtree(CONFIG.WORKSPACE_PATH)
|
| 212 |
|
| 213 |
default_llm_stream_log = partial(print, end="")
|
| 214 |
|
|
|
|
| 239 |
app = FastAPI()
|
| 240 |
|
| 241 |
app.mount(
|
| 242 |
+
"/storage",
|
| 243 |
+
StaticFiles(directory="./storage/"),
|
| 244 |
name="static",
|
| 245 |
)
|
| 246 |
+
|
| 247 |
app.add_api_route(
|
| 248 |
"/api/messages",
|
| 249 |
endpoint=ChatHandler.create_message,
|
|
|
|
| 254 |
|
| 255 |
@app.get("/{catch_all:path}")
|
| 256 |
async def catch_all(request: Request):
|
|
|
|
|
|
|
| 257 |
if request.url.path.startswith("/api"):
|
| 258 |
raise HTTPException(status_code=404)
|
| 259 |
|
| 260 |
+
return RedirectResponse(url="/index.html")
|
| 261 |
+
|
| 262 |
+
|
| 263 |
+
app.mount(
|
| 264 |
+
"/",
|
| 265 |
+
StaticFiles(directory="./static/", html=True),
|
| 266 |
+
name="static",
|
| 267 |
+
)
|
| 268 |
|
| 269 |
|
| 270 |
set_llm_stream_logfunc(llm_stream_log)
|
config/config.yaml
CHANGED
|
@@ -120,3 +120,17 @@ RPM: 10
|
|
| 120 |
# PROMPT_FORMAT: json #json or markdown
|
| 121 |
|
| 122 |
DISABLE_LLM_PROVIDER_CHECK: true
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 120 |
# PROMPT_FORMAT: json #json or markdown
|
| 121 |
|
| 122 |
DISABLE_LLM_PROVIDER_CHECK: true
|
| 123 |
+
STORAGE_TYPE: local # local / s3
|
| 124 |
+
|
| 125 |
+
# for local storage
|
| 126 |
+
LOCAL_ROOT: "storage"
|
| 127 |
+
LOCAL_BASE_URL: "storage"
|
| 128 |
+
|
| 129 |
+
|
| 130 |
+
# for s3 storage
|
| 131 |
+
|
| 132 |
+
# S3_ACCESS_KEY: ""
|
| 133 |
+
# S3_SECRET_KEY: ""
|
| 134 |
+
# S3_ENDPOINT_URL: ""
|
| 135 |
+
# S3_BUCKET: ""
|
| 136 |
+
# S3_SECURE: false
|
software_company.py
CHANGED
|
@@ -62,7 +62,7 @@ class PackProject(Action):
|
|
| 62 |
chunks = []
|
| 63 |
async for chunk in AioZipStream(files, chunksize=32768).stream():
|
| 64 |
chunks.append(chunk)
|
| 65 |
-
return await
|
| 66 |
|
| 67 |
|
| 68 |
class SoftwareCompany(Role):
|
|
@@ -345,22 +345,31 @@ class SoftwareCompany(Role):
|
|
| 345 |
async def upload_file_to_s3(filepath: str, key: str):
|
| 346 |
async with aiofiles.open(filepath, "rb") as f:
|
| 347 |
content = await f.read()
|
| 348 |
-
return await
|
| 349 |
-
|
| 350 |
-
|
| 351 |
-
async def
|
| 352 |
-
|
| 353 |
-
|
| 354 |
-
|
| 355 |
-
|
| 356 |
-
|
| 357 |
-
|
| 358 |
-
|
| 359 |
-
|
| 360 |
-
|
| 361 |
-
|
| 362 |
-
|
| 363 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 364 |
|
| 365 |
|
| 366 |
async def main(idea, **kwargs):
|
|
|
|
| 62 |
chunks = []
|
| 63 |
async for chunk in AioZipStream(files, chunksize=32768).stream():
|
| 64 |
chunks.append(chunk)
|
| 65 |
+
return await get_download_url(b"".join(chunks), key)
|
| 66 |
|
| 67 |
|
| 68 |
class SoftwareCompany(Role):
|
|
|
|
| 345 |
async def upload_file_to_s3(filepath: str, key: str):
|
| 346 |
async with aiofiles.open(filepath, "rb") as f:
|
| 347 |
content = await f.read()
|
| 348 |
+
return await get_download_url(content, key)
|
| 349 |
+
|
| 350 |
+
|
| 351 |
+
async def get_download_url(content: bytes, key: str) -> str:
|
| 352 |
+
if CONFIG.get("STORAGE_TYPE") == "S3":
|
| 353 |
+
session = get_session()
|
| 354 |
+
async with session.create_client(
|
| 355 |
+
"s3",
|
| 356 |
+
aws_secret_access_key=CONFIG.get("S3_SECRET_KEY"),
|
| 357 |
+
aws_access_key_id=CONFIG.get("S3_ACCESS_KEY"),
|
| 358 |
+
endpoint_url=CONFIG.get("S3_ENDPOINT_URL"),
|
| 359 |
+
use_ssl=CONFIG.get("S3_SECURE"),
|
| 360 |
+
) as client:
|
| 361 |
+
# upload object to amazon s3
|
| 362 |
+
bucket = CONFIG.get("S3_BUCKET")
|
| 363 |
+
await client.put_object(Bucket=bucket, Key=key, Body=content)
|
| 364 |
+
return f"{CONFIG.get('S3_ENDPOINT_URL')}/{bucket}/{key}"
|
| 365 |
+
else:
|
| 366 |
+
storage = CONFIG.get("LOCAL_ROOT", "storage")
|
| 367 |
+
base_url = CONFIG.get("LOCAL_BASE_URL", "storage")
|
| 368 |
+
filepath = Path(storage) / key
|
| 369 |
+
filepath.parent.mkdir(exist_ok=True, parents=True)
|
| 370 |
+
async with aiofiles.open(filepath, "wb") as f:
|
| 371 |
+
await f.write(content)
|
| 372 |
+
return f"{base_url}/{key}"
|
| 373 |
|
| 374 |
|
| 375 |
async def main(idea, **kwargs):
|