2024-06-22 12:31:53 +00:00
|
|
|
import uuid
|
2023-10-15 20:04:58 +00:00
|
|
|
import transformers
|
2024-06-23 18:23:15 +00:00
|
|
|
import asyncio
|
2024-06-28 11:14:49 +00:00
|
|
|
import os
|
2024-06-19 13:06:23 +00:00
|
|
|
import torch
|
2024-06-28 11:14:49 +00:00
|
|
|
import aiohttp
|
2023-10-16 10:45:15 +00:00
|
|
|
from fastapi import FastAPI
|
|
|
|
from pydantic import BaseModel
|
2024-06-20 09:26:16 +00:00
|
|
|
from contextlib import asynccontextmanager
|
|
|
|
from apscheduler.schedulers.background import BackgroundScheduler
|
2023-10-16 10:45:15 +00:00
|
|
|
|
2024-06-28 11:14:49 +00:00
|
|
|
# ENV VARS
|
|
|
|
ONEUPTIME_URL = os.getenv("ONEUPTIME_URL")
|
2024-07-12 20:37:03 +00:00
|
|
|
HF_MODEL_NAME = os.getenv("HF_MODEL_NAME")
|
|
|
|
HF_TOKEN = os.getenv("HF_TOKEN")
|
|
|
|
|
|
|
|
if not HF_MODEL_NAME:
|
|
|
|
HF_MODEL_NAME = "meta-llama/Meta-Llama-3-8B-Instruct"
|
2024-07-12 20:39:18 +00:00
|
|
|
print(f"HF_MODEL_NAME not set. Using default model: {HF_MODEL_NAME}")
|
2024-06-28 11:14:49 +00:00
|
|
|
|
|
|
|
if not ONEUPTIME_URL:
|
|
|
|
ONEUPTIME_URL = "https://oneuptime.com"
|
|
|
|
|
2024-07-12 20:37:03 +00:00
|
|
|
if not HF_TOKEN:
|
|
|
|
# Print error and exit
|
|
|
|
print("HF_TOKEN env var is required. This is the Hugging Face API token. You can get it from https://huggingface.co/account/overview. Exiting..")
|
|
|
|
exit()
|
|
|
|
|
2024-06-19 20:58:08 +00:00
|
|
|
# TODO: Store this in redis down the line.
|
|
|
|
items_pending = {}
|
|
|
|
items_processed = {}
|
2024-06-27 13:57:05 +00:00
|
|
|
errors = {}
|
2023-10-16 10:45:15 +00:00
|
|
|
|
2024-06-28 11:14:49 +00:00
|
|
|
async def validateSecretKey(secretKey):
|
|
|
|
try:
|
|
|
|
|
|
|
|
# If no secret key then return false
|
|
|
|
if not secretKey:
|
|
|
|
return False
|
|
|
|
|
|
|
|
async with aiohttp.ClientSession() as session:
|
refactor: Use array of messages in CopilotActionsBase.ts, RefactorCode.ts, ImproveReadme.ts, ImproveVariableNames.ts, FixGrammarAndSpelling.ts, and WriteUnitTests.ts
This refactor changes the code in CopilotActionsBase.ts, RefactorCode.ts, ImproveReadme.ts, ImproveVariableNames.ts, FixGrammarAndSpelling.ts, and WriteUnitTests.ts to use an array of messages instead of a single prompt. Each message in the array contains the content and role of the prompt, improving flexibility and readability.
2024-07-02 11:19:53 +00:00
|
|
|
print(f"Validating secret key")
|
2024-07-09 19:38:29 +00:00
|
|
|
url = f"{ONEUPTIME_URL}/api/copilot-code-repository/is-valid/{secretKey}"
|
2024-06-28 11:14:49 +00:00
|
|
|
async with session.get(url) as response:
|
refactor: Use array of messages in CopilotActionsBase.ts, RefactorCode.ts, ImproveReadme.ts, ImproveVariableNames.ts, FixGrammarAndSpelling.ts, and WriteUnitTests.ts
This refactor changes the code in CopilotActionsBase.ts, RefactorCode.ts, ImproveReadme.ts, ImproveVariableNames.ts, FixGrammarAndSpelling.ts, and WriteUnitTests.ts to use an array of messages instead of a single prompt. Each message in the array contains the content and role of the prompt, improving flexibility and readability.
2024-07-02 11:19:53 +00:00
|
|
|
print(response)
|
2024-06-28 11:14:49 +00:00
|
|
|
if response.status == 200:
|
|
|
|
return True
|
|
|
|
else:
|
|
|
|
return False
|
|
|
|
|
|
|
|
except Exception as e:
|
|
|
|
print(repr(e))
|
|
|
|
return False
|
|
|
|
|
2024-06-27 14:56:22 +00:00
|
|
|
async def job(queue):
|
2024-07-12 20:37:03 +00:00
|
|
|
print("Downlaoding model from Hugging Face: "+HF_MODEL_NAME)
|
|
|
|
|
|
|
|
# check if the model is meta-llama/Meta-Llama-3-8B-Instruct
|
|
|
|
if HF_MODEL_NAME == "meta-llama/Meta-Llama-3-8B-Instruct":
|
|
|
|
print("If you want to use a different model, please set the HF_MODEL_NAME environment variable.")
|
2024-06-20 09:26:16 +00:00
|
|
|
|
2024-07-12 20:37:03 +00:00
|
|
|
print("This may take a while (minutes or sometimes hours) depending on the model size.")
|
|
|
|
|
|
|
|
# model_path = "/app/Models/Meta-Llama-3-8B-Instruct"
|
|
|
|
model_path = HF_MODEL_NAME
|
2024-06-23 18:40:38 +00:00
|
|
|
|
2024-06-27 14:56:22 +00:00
|
|
|
pipe = transformers.pipeline(
|
|
|
|
"text-generation",
|
|
|
|
model=model_path,
|
|
|
|
# use gpu if available
|
|
|
|
device="cuda" if torch.cuda.is_available() else "cpu",
|
2024-07-08 18:46:22 +00:00
|
|
|
# max_new_tokens=8096
|
2024-06-27 14:56:22 +00:00
|
|
|
)
|
2024-07-12 20:37:03 +00:00
|
|
|
|
|
|
|
|
|
|
|
print("Model downloaded.")
|
2024-06-23 20:31:43 +00:00
|
|
|
|
2024-06-27 14:56:22 +00:00
|
|
|
while True:
|
|
|
|
|
|
|
|
random_id = None
|
|
|
|
|
|
|
|
try:
|
2024-06-23 20:31:43 +00:00
|
|
|
# process this item.
|
2024-06-27 14:56:22 +00:00
|
|
|
random_id = await queue.get()
|
2024-06-23 20:31:43 +00:00
|
|
|
print(f"Processing item {random_id}")
|
|
|
|
messages = items_pending[random_id]
|
|
|
|
print(f"Messages:")
|
|
|
|
print(messages)
|
|
|
|
outputs = pipe(messages)
|
|
|
|
items_processed[random_id] = outputs
|
|
|
|
del items_pending[random_id]
|
|
|
|
print(f"Processed item {random_id}")
|
|
|
|
except Exception as e:
|
|
|
|
print(f"Error processing item {random_id}")
|
2024-06-27 13:57:05 +00:00
|
|
|
# store error
|
2024-06-27 14:56:22 +00:00
|
|
|
errors[random_id] = repr(e)
|
2024-06-23 20:31:43 +00:00
|
|
|
# delete from items_pending
|
|
|
|
if random_id in items_pending:
|
|
|
|
del items_pending[random_id]
|
|
|
|
print(e)
|
2024-06-20 09:26:16 +00:00
|
|
|
|
2024-06-23 18:23:15 +00:00
|
|
|
|
|
|
|
|
|
|
|
|
2024-06-20 09:26:16 +00:00
|
|
|
@asynccontextmanager
|
|
|
|
async def lifespan(app:FastAPI):
|
2024-06-27 14:56:22 +00:00
|
|
|
queue = asyncio.Queue()
|
|
|
|
app.model_queue = queue
|
|
|
|
asyncio.create_task(job(queue))
|
2024-06-20 09:26:16 +00:00
|
|
|
yield
|
|
|
|
|
2023-10-16 10:45:15 +00:00
|
|
|
# Declare a Pydantic model for the request body
|
|
|
|
class Prompt(BaseModel):
|
2024-06-27 20:11:57 +00:00
|
|
|
messages: list
|
2024-07-12 20:17:57 +00:00
|
|
|
# secretkey: str
|
2023-10-16 10:45:15 +00:00
|
|
|
|
2024-06-19 20:58:08 +00:00
|
|
|
# Declare a Pydantic model for the request body
|
|
|
|
class PromptResult(BaseModel):
|
|
|
|
id: str
|
2024-07-12 20:17:57 +00:00
|
|
|
# secretkey: str
|
2024-06-19 20:58:08 +00:00
|
|
|
|
2024-06-20 09:26:16 +00:00
|
|
|
app = FastAPI(lifespan=lifespan)
|
2023-10-16 10:45:15 +00:00
|
|
|
|
2024-06-19 13:06:23 +00:00
|
|
|
@app.get("/")
|
|
|
|
async def root():
|
2024-06-22 12:31:53 +00:00
|
|
|
return {"status": "ok"}
|
2024-06-19 13:06:23 +00:00
|
|
|
|
2024-07-08 18:46:22 +00:00
|
|
|
@app.get("/status")
|
|
|
|
async def status():
|
|
|
|
return {"status": "ok"}
|
|
|
|
|
2023-10-16 10:45:15 +00:00
|
|
|
@app.post("/prompt/")
|
|
|
|
async def create_item(prompt: Prompt):
|
|
|
|
|
2024-06-27 20:19:44 +00:00
|
|
|
try:
|
|
|
|
# If not prompt then return bad request error
|
|
|
|
if not prompt:
|
|
|
|
return {"error": "Prompt is required"}
|
|
|
|
|
2024-06-28 11:14:49 +00:00
|
|
|
# Validate the secret key
|
2024-07-12 20:17:57 +00:00
|
|
|
# is_valid = await validateSecretKey(prompt.secretkey)
|
2024-06-28 11:14:49 +00:00
|
|
|
|
2024-07-12 20:17:57 +00:00
|
|
|
# if not is_valid:
|
|
|
|
# print("Invalid secret key")
|
|
|
|
# return {"error": "Invalid secret key"}
|
2024-06-28 11:14:49 +00:00
|
|
|
|
2024-06-27 20:19:44 +00:00
|
|
|
# messages are in str format. We need to convert them fron json [] to list
|
|
|
|
messages = prompt.messages
|
2023-10-16 10:45:15 +00:00
|
|
|
|
2024-06-27 20:19:44 +00:00
|
|
|
# Log prompt to console
|
|
|
|
print(messages)
|
2024-06-18 17:42:11 +00:00
|
|
|
|
2024-06-27 20:19:44 +00:00
|
|
|
# Generate UUID
|
|
|
|
random_id = str(uuid.uuid4())
|
2024-06-19 20:58:08 +00:00
|
|
|
|
2024-06-27 20:19:44 +00:00
|
|
|
# add to queue
|
2024-06-19 20:58:08 +00:00
|
|
|
|
2024-06-27 20:19:44 +00:00
|
|
|
items_pending[random_id] = messages
|
|
|
|
await app.model_queue.put(random_id)
|
2024-06-19 20:58:08 +00:00
|
|
|
|
2024-06-27 20:19:44 +00:00
|
|
|
# Return response
|
|
|
|
return {
|
|
|
|
"id": random_id,
|
|
|
|
"status": "queued"
|
|
|
|
}
|
|
|
|
except Exception as e:
|
2024-06-27 20:23:24 +00:00
|
|
|
print(e)
|
2024-06-27 20:19:44 +00:00
|
|
|
return {"error": repr(e)}
|
2024-06-19 20:58:08 +00:00
|
|
|
|
2024-06-28 11:14:49 +00:00
|
|
|
# Disable this API in production
|
2024-06-22 12:31:53 +00:00
|
|
|
@app.get("/queue-status/")
|
|
|
|
async def queue_status():
|
2024-06-27 20:19:44 +00:00
|
|
|
try:
|
|
|
|
return {"pending": items_pending, "processed": items_processed, "queue": app.model_queue.qsize(), "errors": errors}
|
|
|
|
except Exception as e:
|
2024-06-27 20:23:24 +00:00
|
|
|
print(e)
|
2024-06-27 20:19:44 +00:00
|
|
|
return {"error": repr(e)}
|
2024-06-22 12:31:53 +00:00
|
|
|
|
2024-06-19 20:58:08 +00:00
|
|
|
@app.post("/prompt-result/")
|
|
|
|
async def prompt_status(prompt_status: PromptResult):
|
2024-06-27 20:19:44 +00:00
|
|
|
try:
|
2024-06-19 20:58:08 +00:00
|
|
|
# Log prompt status to console
|
|
|
|
print(prompt_status)
|
2024-06-28 11:14:49 +00:00
|
|
|
|
|
|
|
# Validate the secret key
|
2024-07-12 20:17:57 +00:00
|
|
|
# is_valid = await validateSecretKey(prompt_status.secretkey)
|
2024-06-28 11:14:49 +00:00
|
|
|
|
2024-07-12 20:17:57 +00:00
|
|
|
# if not is_valid:
|
|
|
|
# print("Invalid secret key")
|
|
|
|
# return {"error": "Invalid secret key"}
|
2024-06-28 11:14:49 +00:00
|
|
|
|
2024-06-19 20:58:08 +00:00
|
|
|
# If not prompt status then return bad request error
|
|
|
|
if not prompt_status:
|
|
|
|
return {"error": "Prompt status is required"}
|
|
|
|
|
|
|
|
# check if item is processed.
|
|
|
|
if prompt_status.id in items_processed:
|
|
|
|
|
|
|
|
|
|
|
|
return_value = {
|
|
|
|
"id": prompt_status.id,
|
|
|
|
"status": "processed",
|
|
|
|
"output": items_processed[prompt_status.id]
|
|
|
|
}
|
|
|
|
|
|
|
|
# delete from item_processed
|
|
|
|
del items_processed[prompt_status.id]
|
|
|
|
|
|
|
|
return return_value
|
|
|
|
else:
|
2024-06-20 10:00:07 +00:00
|
|
|
|
|
|
|
status = "not found"
|
|
|
|
|
|
|
|
if prompt_status.id in items_pending:
|
|
|
|
status = "pending"
|
|
|
|
|
2024-06-19 20:58:08 +00:00
|
|
|
return {
|
|
|
|
"id": prompt_status.id,
|
2024-06-20 10:00:07 +00:00
|
|
|
"status": status
|
2024-06-19 20:58:08 +00:00
|
|
|
}
|
2024-06-27 20:19:44 +00:00
|
|
|
except Exception as e:
|
2024-06-27 20:23:24 +00:00
|
|
|
print(e)
|
2024-06-27 20:19:44 +00:00
|
|
|
return {"error": repr(e)}
|
2024-06-19 20:58:08 +00:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|