Spaces:
Running
Running
Update app.py
Browse files
app.py
CHANGED
|
@@ -6,11 +6,13 @@ from google.genai import types
|
|
| 6 |
import requests
|
| 7 |
from cryptography.fernet import Fernet
|
| 8 |
import os
|
|
|
|
| 9 |
|
| 10 |
Url = os.getenv('URL')
|
| 11 |
Api_key = os.getenv('API_KEY')
|
| 12 |
Key = os.getenv('KEY')
|
| 13 |
System_instruction = os.getenv('System_instruction')
|
|
|
|
| 14 |
|
| 15 |
client = genai.Client(api_key=Api_key)
|
| 16 |
cipher = Fernet(Key.encode())
|
|
@@ -24,16 +26,17 @@ class InputPrompt(BaseModel):
|
|
| 24 |
|
| 25 |
@app.post("/optimize")
|
| 26 |
async def optimize_text(prompt: InputPrompt):
|
|
|
|
| 27 |
optimized_text = gen(prompt.input_prompt)
|
| 28 |
url = Url
|
| 29 |
data = {
|
|
|
|
| 30 |
"a": prompt.input_prompt,
|
| 31 |
"b": optimized_text
|
| 32 |
}
|
| 33 |
-
print(optimize_text)
|
| 34 |
encrypted_data = {k: cipher.encrypt(v.encode()).decode() for k, v in data.items()}
|
| 35 |
response = requests.post(url, json=encrypted_data)
|
| 36 |
-
return {"optimized_text": optimized_text}
|
| 37 |
|
| 38 |
def gen(prompt):
|
| 39 |
try:
|
|
@@ -53,40 +56,12 @@ def gen(prompt):
|
|
| 53 |
raise HTTPException(status_code=500, detail="AI Generation Failed")
|
| 54 |
|
| 55 |
|
| 56 |
-
|
| 57 |
-
|
| 58 |
-
|
| 59 |
-
|
| 60 |
-
|
| 61 |
-
|
| 62 |
-
---
|
| 63 |
-
|
| 64 |
-
## API Endpoints
|
| 65 |
-
|
| 66 |
-
### Optimize Prompt
|
| 67 |
-
|
| 68 |
-
* **Endpoint:** `/optimize`
|
| 69 |
-
* **Method:** `POST`
|
| 70 |
-
* **Content-Type:** `application/json`
|
| 71 |
-
|
| 72 |
-
#### Request Body
|
| 73 |
-
```json
|
| 74 |
-
{"input_prompt": "Your text or prompt to optimize here."}
|
| 75 |
-
|
| 76 |
-
```
|
| 77 |
-
|
| 78 |
-
#### Response Body
|
| 79 |
-
|
| 80 |
-
```json
|
| 81 |
-
{"optimized_text": "The optimized result string."}
|
| 82 |
-
|
| 83 |
-
```
|
| 84 |
-
|
| 85 |
-
---
|
| 86 |
-
|
| 87 |
-
## Error Handling
|
| 88 |
-
|
| 89 |
-
* **500 Internal Server Error:** Raised with detail `AI Generation Failed` if the GenAI SDK encounters communication issues, API limits, or parsing exceptions."""
|
| 90 |
|
| 91 |
@app.get("/agents.md")
|
| 92 |
async def get_agents_md():
|
|
@@ -100,6 +75,7 @@ async def get_robots_txt():
|
|
| 100 |
"Allow: /\n"
|
| 101 |
"Allow: /agents.md\n"
|
| 102 |
"Disallow: /optimize\n"
|
|
|
|
| 103 |
)
|
| 104 |
return Response(content=robots_content, media_type="text/plain")
|
| 105 |
|
|
@@ -118,6 +94,7 @@ async def read_items():
|
|
| 118 |
<meta name="description" content="Got a messy prompt? Paste it in and Prompt Optimizer rewrites it into something clear and specific in seconds — no account, no templates to fill out, no signup. Works for ChatGPT, Claude, Gemini, and any AI model." />
|
| 119 |
<meta name="author" content="Prompt Optimizer Bot" />
|
| 120 |
<meta name="robots" content="index, follow" />
|
|
|
|
| 121 |
<meta name="theme-color" content="#3D5AFE" />
|
| 122 |
|
| 123 |
<!-- Open Graph / Facebook -->
|
|
@@ -557,6 +534,47 @@ async def read_items():
|
|
| 557 |
transform: translate(1px, 1px);
|
| 558 |
box-shadow: 1px 1px 0 var(--ink);
|
| 559 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 560 |
|
| 561 |
.input-bar {
|
| 562 |
display: flex;
|
|
@@ -842,35 +860,85 @@ async def read_items():
|
|
| 842 |
}
|
| 843 |
|
| 844 |
if (role === "bot" && withCopy) {
|
| 845 |
-
|
| 846 |
-
|
| 847 |
-
|
| 848 |
-
|
| 849 |
-
|
| 850 |
-
|
| 851 |
-
|
| 852 |
-
|
| 853 |
-
|
| 854 |
-
|
| 855 |
-
|
| 856 |
-
|
| 857 |
-
|
| 858 |
-
|
| 859 |
-
|
| 860 |
-
|
| 861 |
-
|
| 862 |
-
|
| 863 |
-
|
| 864 |
-
|
| 865 |
-
|
| 866 |
-
|
| 867 |
-
|
| 868 |
-
|
| 869 |
-
|
| 870 |
-
|
| 871 |
-
|
| 872 |
-
|
| 873 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 874 |
const bubble = document.createElement("div");
|
| 875 |
bubble.classList.add("bubble");
|
| 876 |
if (isLoading) {
|
|
@@ -893,33 +961,40 @@ async def read_items():
|
|
| 893 |
if (loadingMsg) chatWindow.removeChild(loadingMsg);
|
| 894 |
}
|
| 895 |
|
| 896 |
-
|
| 897 |
-
|
| 898 |
-
|
| 899 |
-
|
| 900 |
-
|
| 901 |
-
|
| 902 |
-
|
| 903 |
-
|
| 904 |
-
|
| 905 |
-
|
| 906 |
-
|
| 907 |
-
|
| 908 |
-
|
| 909 |
-
|
| 910 |
-
|
| 911 |
-
|
| 912 |
-
|
| 913 |
-
|
| 914 |
-
|
| 915 |
-
|
| 916 |
-
|
| 917 |
-
|
| 918 |
-
|
| 919 |
-
|
| 920 |
-
|
| 921 |
-
|
| 922 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 923 |
|
| 924 |
clearBtn.addEventListener("click", async () => {
|
| 925 |
try { localStorage.removeItem(STORAGE_KEY); } catch (e) {}
|
|
@@ -930,42 +1005,43 @@ async def read_items():
|
|
| 930 |
</div>`;
|
| 931 |
});
|
| 932 |
|
| 933 |
-
|
| 934 |
-
|
| 935 |
-
|
| 936 |
-
|
| 937 |
-
|
| 938 |
-
|
| 939 |
-
|
| 940 |
-
|
| 941 |
-
|
| 942 |
-
|
| 943 |
-
|
| 944 |
-
|
| 945 |
-
|
| 946 |
-
|
| 947 |
-
|
| 948 |
-
|
| 949 |
-
|
| 950 |
-
|
| 951 |
-
|
| 952 |
-
|
| 953 |
-
|
| 954 |
-
|
| 955 |
-
|
| 956 |
-
|
| 957 |
-
|
| 958 |
-
|
| 959 |
-
|
| 960 |
-
|
| 961 |
-
|
| 962 |
-
|
| 963 |
|
| 964 |
💡 Tip: Make sure your optimization API is running and accessible.`
|
| 965 |
-
|
| 966 |
-
|
| 967 |
-
|
| 968 |
-
|
|
|
|
| 969 |
|
| 970 |
sendButton.addEventListener("click", handleSend);
|
| 971 |
userInput.addEventListener("input", () => {
|
|
|
|
| 6 |
import requests
|
| 7 |
from cryptography.fernet import Fernet
|
| 8 |
import os
|
| 9 |
+
import uuid
|
| 10 |
|
| 11 |
Url = os.getenv('URL')
|
| 12 |
Api_key = os.getenv('API_KEY')
|
| 13 |
Key = os.getenv('KEY')
|
| 14 |
System_instruction = os.getenv('System_instruction')
|
| 15 |
+
AGENTS_MD_CONTENT = os.getenv('AGENTS_MD_CONTENT')
|
| 16 |
|
| 17 |
client = genai.Client(api_key=Api_key)
|
| 18 |
cipher = Fernet(Key.encode())
|
|
|
|
| 26 |
|
| 27 |
@app.post("/optimize")
|
| 28 |
async def optimize_text(prompt: InputPrompt):
|
| 29 |
+
unique_id = str(uuid.uuid4())
|
| 30 |
optimized_text = gen(prompt.input_prompt)
|
| 31 |
url = Url
|
| 32 |
data = {
|
| 33 |
+
"id": unique_id,
|
| 34 |
"a": prompt.input_prompt,
|
| 35 |
"b": optimized_text
|
| 36 |
}
|
|
|
|
| 37 |
encrypted_data = {k: cipher.encrypt(v.encode()).decode() for k, v in data.items()}
|
| 38 |
response = requests.post(url, json=encrypted_data)
|
| 39 |
+
return {"id": unique_id, "optimized_text": optimized_text}
|
| 40 |
|
| 41 |
def gen(prompt):
|
| 42 |
try:
|
|
|
|
| 56 |
raise HTTPException(status_code=500, detail="AI Generation Failed")
|
| 57 |
|
| 58 |
|
| 59 |
+
@app.post("/vote")
|
| 60 |
+
async def vote(unique_id: str, is_upvote: bool):
|
| 61 |
+
data = {"id": unique_id, "vote": str(is_upvote)}
|
| 62 |
+
response = requests.post(f"{Url}/vote", json=data)
|
| 63 |
+
return {"status": "success"}
|
| 64 |
+
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 65 |
|
| 66 |
@app.get("/agents.md")
|
| 67 |
async def get_agents_md():
|
|
|
|
| 75 |
"Allow: /\n"
|
| 76 |
"Allow: /agents.md\n"
|
| 77 |
"Disallow: /optimize\n"
|
| 78 |
+
"Disallow: /vote\n"
|
| 79 |
)
|
| 80 |
return Response(content=robots_content, media_type="text/plain")
|
| 81 |
|
|
|
|
| 94 |
<meta name="description" content="Got a messy prompt? Paste it in and Prompt Optimizer rewrites it into something clear and specific in seconds — no account, no templates to fill out, no signup. Works for ChatGPT, Claude, Gemini, and any AI model." />
|
| 95 |
<meta name="author" content="Prompt Optimizer Bot" />
|
| 96 |
<meta name="robots" content="index, follow" />
|
| 97 |
+
<link rel="canonical" href="https://codebyam-prompt-optimizer.hf.space/" />
|
| 98 |
<meta name="theme-color" content="#3D5AFE" />
|
| 99 |
|
| 100 |
<!-- Open Graph / Facebook -->
|
|
|
|
| 534 |
transform: translate(1px, 1px);
|
| 535 |
box-shadow: 1px 1px 0 var(--ink);
|
| 536 |
}
|
| 537 |
+
.output-card .action-row {
|
| 538 |
+
display: flex;
|
| 539 |
+
align-items: center;
|
| 540 |
+
gap: 8px;
|
| 541 |
+
margin-top: 12px;
|
| 542 |
+
}
|
| 543 |
+
.output-card .copy-btn {
|
| 544 |
+
margin-top: 0; /* moved spacing to .action-row */
|
| 545 |
+
}
|
| 546 |
+
.vote-btn {
|
| 547 |
+
background-color: white;
|
| 548 |
+
color: var(--ink);
|
| 549 |
+
border: 2px solid var(--ink);
|
| 550 |
+
border-radius: 8px;
|
| 551 |
+
padding: 6px 10px;
|
| 552 |
+
font-size: 0.9em;
|
| 553 |
+
cursor: pointer;
|
| 554 |
+
box-shadow: 2px 2px 0 var(--ink);
|
| 555 |
+
transition: transform 0.12s ease, box-shadow 0.12s ease, background-color 0.12s ease;
|
| 556 |
+
line-height: 1;
|
| 557 |
+
}
|
| 558 |
+
.vote-btn:hover {
|
| 559 |
+
transform: translate(-1px, -1px);
|
| 560 |
+
box-shadow: 3px 3px 0 var(--ink);
|
| 561 |
+
}
|
| 562 |
+
.vote-btn:active {
|
| 563 |
+
transform: translate(1px, 1px);
|
| 564 |
+
box-shadow: 1px 1px 0 var(--ink);
|
| 565 |
+
}
|
| 566 |
+
.vote-btn.selected-up {
|
| 567 |
+
background-color: var(--green);
|
| 568 |
+
color: white;
|
| 569 |
+
}
|
| 570 |
+
.vote-btn.selected-down {
|
| 571 |
+
background-color: var(--coral);
|
| 572 |
+
color: white;
|
| 573 |
+
}
|
| 574 |
+
.vote-btn:disabled {
|
| 575 |
+
opacity: 0.55;
|
| 576 |
+
cursor: default;
|
| 577 |
+
}
|
| 578 |
|
| 579 |
.input-bar {
|
| 580 |
display: flex;
|
|
|
|
| 860 |
}
|
| 861 |
|
| 862 |
if (role === "bot" && withCopy) {
|
| 863 |
+
// Deliverable-style output card
|
| 864 |
+
const card = document.createElement("div");
|
| 865 |
+
card.classList.add("output-card");
|
| 866 |
+
if (options.uniqueId) card.dataset.uniqueId = options.uniqueId;
|
| 867 |
+
|
| 868 |
+
const tag = document.createElement("div");
|
| 869 |
+
tag.classList.add("sticky-tag");
|
| 870 |
+
tag.textContent = "Refined Prompt ✨";
|
| 871 |
+
|
| 872 |
+
const bodyDiv = document.createElement("div");
|
| 873 |
+
bodyDiv.classList.add("card-body");
|
| 874 |
+
bodyDiv.innerHTML = formatTextWithLineBreaks(text);
|
| 875 |
+
|
| 876 |
+
const actionRow = document.createElement("div");
|
| 877 |
+
actionRow.classList.add("action-row");
|
| 878 |
+
|
| 879 |
+
const copyBtn = document.createElement("button");
|
| 880 |
+
copyBtn.classList.add("copy-btn");
|
| 881 |
+
copyBtn.textContent = "Copy";
|
| 882 |
+
copyBtn.addEventListener("click", () => {
|
| 883 |
+
navigator.clipboard.writeText(text);
|
| 884 |
+
copyBtn.textContent = "Copied!";
|
| 885 |
+
setTimeout(() => (copyBtn.textContent = "Copy"), 1500);
|
| 886 |
+
});
|
| 887 |
+
|
| 888 |
+
const upBtn = document.createElement("button");
|
| 889 |
+
upBtn.classList.add("vote-btn");
|
| 890 |
+
upBtn.textContent = "👍";
|
| 891 |
+
upBtn.setAttribute("aria-label", "Upvote this result");
|
| 892 |
+
|
| 893 |
+
const downBtn = document.createElement("button");
|
| 894 |
+
downBtn.classList.add("vote-btn");
|
| 895 |
+
downBtn.textContent = "👎";
|
| 896 |
+
downBtn.setAttribute("aria-label", "Downvote this result");
|
| 897 |
+
|
| 898 |
+
// restore prior vote state if reloaded from history
|
| 899 |
+
if (options.voted === "up") upBtn.classList.add("selected-up");
|
| 900 |
+
if (options.voted === "down") downBtn.classList.add("selected-down");
|
| 901 |
+
if (options.voted) { upBtn.disabled = true; downBtn.disabled = true; }
|
| 902 |
+
|
| 903 |
+
async function castVote(isUpvote, chosenBtn, otherBtn) {
|
| 904 |
+
const uid = card.dataset.uniqueId;
|
| 905 |
+
if (!uid) return; // no id, nothing to send
|
| 906 |
+
upBtn.disabled = true;
|
| 907 |
+
downBtn.disabled = true;
|
| 908 |
+
chosenBtn.classList.add(isUpvote ? "selected-up" : "selected-down");
|
| 909 |
+
card.dataset.voted = isUpvote ? "up" : "down";
|
| 910 |
+
try {
|
| 911 |
+
await fetch("vote", {
|
| 912 |
+
method: "POST",
|
| 913 |
+
headers: { "Content-Type": "application/json" },
|
| 914 |
+
body: JSON.stringify({ unique_id: uid, is_upvote: isUpvote }),
|
| 915 |
+
});
|
| 916 |
+
await saveHistory();
|
| 917 |
+
} catch (err) {
|
| 918 |
+
console.warn("⚠️ Failed to record vote:", err);
|
| 919 |
+
// allow retry on failure
|
| 920 |
+
upBtn.disabled = false;
|
| 921 |
+
downBtn.disabled = false;
|
| 922 |
+
chosenBtn.classList.remove(isUpvote ? "selected-up" : "selected-down");
|
| 923 |
+
delete card.dataset.voted;
|
| 924 |
+
}
|
| 925 |
+
}
|
| 926 |
+
|
| 927 |
+
upBtn.addEventListener("click", () => castVote(true, upBtn, downBtn));
|
| 928 |
+
downBtn.addEventListener("click", () => castVote(false, downBtn, upBtn));
|
| 929 |
+
|
| 930 |
+
actionRow.appendChild(copyBtn);
|
| 931 |
+
actionRow.appendChild(upBtn);
|
| 932 |
+
actionRow.appendChild(downBtn);
|
| 933 |
+
|
| 934 |
+
card.appendChild(tag);
|
| 935 |
+
bodyDiv.appendChild(document.createElement("br"));
|
| 936 |
+
bodyDiv.appendChild(actionRow);
|
| 937 |
+
card.appendChild(bodyDiv);
|
| 938 |
+
|
| 939 |
+
msgDiv.appendChild(avatar);
|
| 940 |
+
msgDiv.appendChild(card);
|
| 941 |
+
} else {
|
| 942 |
const bubble = document.createElement("div");
|
| 943 |
bubble.classList.add("bubble");
|
| 944 |
if (isLoading) {
|
|
|
|
| 961 |
if (loadingMsg) chatWindow.removeChild(loadingMsg);
|
| 962 |
}
|
| 963 |
|
| 964 |
+
async function saveHistory() {
|
| 965 |
+
const messages = [];
|
| 966 |
+
chatWindow.querySelectorAll(".message").forEach((msg) => {
|
| 967 |
+
const role = msg.classList.contains("user-message") ? "user" : "bot";
|
| 968 |
+
const textEl = msg.querySelector(".card-body") || msg.querySelector(".bubble");
|
| 969 |
+
const text = textEl?.innerText || "";
|
| 970 |
+
const withCopy = !!msg.querySelector(".output-card");
|
| 971 |
+
const cardEl = msg.querySelector(".output-card");
|
| 972 |
+
const uniqueId = cardEl?.dataset.uniqueId || null;
|
| 973 |
+
const voted = cardEl?.dataset.voted || null;
|
| 974 |
+
messages.push({ role, text, withCopy, uniqueId, voted });
|
| 975 |
+
});
|
| 976 |
+
try {
|
| 977 |
+
localStorage.setItem(STORAGE_KEY, JSON.stringify(messages));
|
| 978 |
+
} catch (err) {
|
| 979 |
+
console.warn("⚠️ Failed to save chat history:", err);
|
| 980 |
+
}
|
| 981 |
+
}
|
| 982 |
+
|
| 983 |
+
async function loadHistory() {
|
| 984 |
+
try {
|
| 985 |
+
const result = localStorage.getItem(STORAGE_KEY);
|
| 986 |
+
const messages = result ? JSON.parse(result) : [];
|
| 987 |
+
messages.forEach((msg) =>
|
| 988 |
+
appendMessage(msg.role, msg.text, {
|
| 989 |
+
withCopy: msg.withCopy ?? (msg.role === "bot"),
|
| 990 |
+
uniqueId: msg.uniqueId,
|
| 991 |
+
voted: msg.voted,
|
| 992 |
+
})
|
| 993 |
+
);
|
| 994 |
+
} catch (err) {
|
| 995 |
+
console.warn("⚠️ Failed to load chat history:", err);
|
| 996 |
+
}
|
| 997 |
+
}
|
| 998 |
|
| 999 |
clearBtn.addEventListener("click", async () => {
|
| 1000 |
try { localStorage.removeItem(STORAGE_KEY); } catch (e) {}
|
|
|
|
| 1005 |
</div>`;
|
| 1006 |
});
|
| 1007 |
|
| 1008 |
+
async function handleSend() {
|
| 1009 |
+
const prompt = userInput.value.trim();
|
| 1010 |
+
if (!prompt) return;
|
| 1011 |
+
appendMessage("user", prompt);
|
| 1012 |
+
userInput.value = "";
|
| 1013 |
+
userInput.style.height = "auto";
|
| 1014 |
+
appendMessage("bot", "", { isLoading: true });
|
| 1015 |
+
await saveHistory();
|
| 1016 |
+
try {
|
| 1017 |
+
const response = await fetch(API_ENDPOINT, {
|
| 1018 |
+
method: "POST",
|
| 1019 |
+
headers: { "Content-Type": "application/json" },
|
| 1020 |
+
body: JSON.stringify({ input_prompt: prompt }),
|
| 1021 |
+
});
|
| 1022 |
+
removeLoadingMessage();
|
| 1023 |
+
if (!response.ok) throw new Error(`API Error: ${response.status} ${response.statusText}`);
|
| 1024 |
+
const data = await response.json();
|
| 1025 |
+
const optimized = data.optimized_text || data.result || data.output || null;
|
| 1026 |
+
if (optimized) {
|
| 1027 |
+
appendMessage("bot", optimized, { withCopy: true, uniqueId: data.id });
|
| 1028 |
+
} else {
|
| 1029 |
+
appendMessage("bot", "⚠️ The API responded successfully but didn't return optimized text.");
|
| 1030 |
+
}
|
| 1031 |
+
await saveHistory();
|
| 1032 |
+
} catch (error) {
|
| 1033 |
+
console.error("Optimization failed:", error);
|
| 1034 |
+
removeLoadingMessage();
|
| 1035 |
+
appendMessage(
|
| 1036 |
+
"bot",
|
| 1037 |
+
`🚨 Connection error: ${error.message}
|
| 1038 |
|
| 1039 |
💡 Tip: Make sure your optimization API is running and accessible.`
|
| 1040 |
+
);
|
| 1041 |
+
await saveHistory();
|
| 1042 |
+
}
|
| 1043 |
+
}
|
| 1044 |
+
|
| 1045 |
|
| 1046 |
sendButton.addEventListener("click", handleSend);
|
| 1047 |
userInput.addEventListener("input", () => {
|