-
Notifications
You must be signed in to change notification settings - Fork 2.1k
feat: Create MVP for Academic Weapon AI Suite #933
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
* Serving Flask app 'app' | ||
* Debug mode: off | ||
[31m[1mWARNING: This is a development server. Do not use it in a production deployment. Use a production WSGI server instead.[0m | ||
* Running on all addresses (0.0.0.0) | ||
* Running on http://127.0.0.1:8080 | ||
* Running on http://192.168.0.2:8080 | ||
[33mPress CTRL+C to quit[0m | ||
Original file line number | Diff line number | Diff line change | ||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
@@ -0,0 +1,97 @@ | ||||||||||||||||||||||
from flask import Flask, render_template, request, jsonify | ||||||||||||||||||||||
|
||||||||||||||||||||||
app = Flask(__name__) | ||||||||||||||||||||||
|
||||||||||||||||||||||
@app.route('/') | ||||||||||||||||||||||
def index(): | ||||||||||||||||||||||
# This will serve the main command interface. | ||||||||||||||||||||||
return render_template('index.html') | ||||||||||||||||||||||
|
||||||||||||||||||||||
@app.route('/api/insta-essay', methods=['POST']) | ||||||||||||||||||||||
def insta_essay(): | ||||||||||||||||||||||
""" | ||||||||||||||||||||||
Simulates the generation of a high-quality essay. | ||||||||||||||||||||||
The hook to demonstrate power. | ||||||||||||||||||||||
""" | ||||||||||||||||||||||
# In a real scenario, we'd process the request data (prompt, rubric, etc.) | ||||||||||||||||||||||
# and call an LLM API. For this MVP, we return a simulated result. | ||||||||||||||||||||||
data = request.json | ||||||||||||||||||||||
print(f"Received for InstaEssay: {data}") | ||||||||||||||||||||||
Comment on lines
+18
to
+19
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Using This comment also applies to lines 33-34, 52-53, and 76-77.
Suggested change
|
||||||||||||||||||||||
|
||||||||||||||||||||||
simulated_essay = """ | ||||||||||||||||||||||
The socio-economic ramifications of post-industrial capitalism have been a subject of extensive debate among scholars. This essay delineates the primary arguments, focusing on the dichotomy between neoliberal proponents and their Marxist critics. The former argue for market-led growth, citing empirical evidence of poverty reduction, while the latter highlight the exacerbation of inequality and labor exploitation. Ultimately, a synthesis of these perspectives suggests that while globalization has generated unprecedented wealth, its distribution remains fundamentally inequitable, necessitating robust state intervention. | ||||||||||||||||||||||
|
||||||||||||||||||||||
(Generated via AcademicWeapon.ai - The Unfair Advantage) | ||||||||||||||||||||||
""" | ||||||||||||||||||||||
Comment on lines
+21
to
+25
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The project's style guide suggests that long string variables should have their content indented for better readability.1 This makes the code cleaner and more consistent.
Suggested change
Style Guide ReferencesFootnotes |
||||||||||||||||||||||
return jsonify({"result": simulated_essay.strip()}) | ||||||||||||||||||||||
|
||||||||||||||||||||||
@app.route('/api/lit-review', methods=['POST']) | ||||||||||||||||||||||
def lit_review(): | ||||||||||||||||||||||
""" | ||||||||||||||||||||||
Simulates the generation of a literature review. | ||||||||||||||||||||||
""" | ||||||||||||||||||||||
data = request.json | ||||||||||||||||||||||
print(f"Received for LitReview: {data}") | ||||||||||||||||||||||
|
||||||||||||||||||||||
simulated_review = """ | ||||||||||||||||||||||
**Literature Review: The Impact of AI on Higher Education** | ||||||||||||||||||||||
|
||||||||||||||||||||||
1. **Smith (2021), "The Algorithmic Tutor"**: Found that AI-driven personalized learning platforms increased student engagement by 35%. | ||||||||||||||||||||||
2. **Jones & Wang (2022), "Automating Academia"**: Raised ethical concerns regarding algorithmic bias in automated grading systems. | ||||||||||||||||||||||
3. **Gupta (2020), "Computational Pedagogy"**: Argued that AI tools could free up educators to focus on higher-order conceptual teaching. | ||||||||||||||||||||||
|
||||||||||||||||||||||
(Generated via AcademicWeapon.ai - The Unfair Advantage) | ||||||||||||||||||||||
""" | ||||||||||||||||||||||
return jsonify({"result": simulated_review.strip()}) | ||||||||||||||||||||||
|
||||||||||||||||||||||
@app.route('/api/exam-cram', methods=['POST']) | ||||||||||||||||||||||
def exam_cram(): | ||||||||||||||||||||||
""" | ||||||||||||||||||||||
Simulates the generation of a study guide from uploaded materials. | ||||||||||||||||||||||
""" | ||||||||||||||||||||||
data = request.json | ||||||||||||||||||||||
print(f"Received for ExamCram: {data}") | ||||||||||||||||||||||
|
||||||||||||||||||||||
simulated_guide = """ | ||||||||||||||||||||||
**ExamCram Study Guide: Microeconomics 101** | ||||||||||||||||||||||
|
||||||||||||||||||||||
**Key Concepts:** | ||||||||||||||||||||||
- **Supply and Demand:** As price increases, supply increases and demand decreases. Equilibrium is where they intersect. | ||||||||||||||||||||||
- **Elasticity:** Measures sensitivity of demand/supply to price changes. | ||||||||||||||||||||||
- **Opportunity Cost:** The value of the next-best alternative forgone. | ||||||||||||||||||||||
|
||||||||||||||||||||||
**Potential Questions:** | ||||||||||||||||||||||
1. Explain the concept of market equilibrium. | ||||||||||||||||||||||
2. What are the determinants of price elasticity of demand? | ||||||||||||||||||||||
|
||||||||||||||||||||||
(Generated via AcademicWeapon.ai - The Unfair Advantage) | ||||||||||||||||||||||
""" | ||||||||||||||||||||||
return jsonify({"result": simulated_guide.strip()}) | ||||||||||||||||||||||
|
||||||||||||||||||||||
@app.route('/api/presentation-bot', methods=['POST']) | ||||||||||||||||||||||
def presentation_bot(): | ||||||||||||||||||||||
""" | ||||||||||||||||||||||
Simulates the generation of a presentation. | ||||||||||||||||||||||
""" | ||||||||||||||||||||||
data = request.json | ||||||||||||||||||||||
print(f"Received for PresentationBot: {data}") | ||||||||||||||||||||||
|
||||||||||||||||||||||
simulated_slides = """ | ||||||||||||||||||||||
**Presentation: The Future of Renewable Energy** | ||||||||||||||||||||||
|
||||||||||||||||||||||
- **Slide 1: Title Slide** | ||||||||||||||||||||||
- **Slide 2: The Problem:** Climate Change & Fossil Fuel Dependency | ||||||||||||||||||||||
- **Slide 3: Solution Overview:** Solar, Wind, Geothermal | ||||||||||||||||||||||
- **Slide 4: Deep Dive: Solar Power** (Technology, Costs, Benefits) | ||||||||||||||||||||||
- **Slide 5: Deep Dive: Wind Power** (Turbine tech, Onshore vs. Offshore) | ||||||||||||||||||||||
- **Slide 6: Economic Viability & Market Trends** | ||||||||||||||||||||||
- **Slide 7: Challenges & The Path Forward** | ||||||||||||||||||||||
- **Slide 8: Q&A** | ||||||||||||||||||||||
|
||||||||||||||||||||||
(Generated via AcademicWeapon.ai - The Unfair Advantage) | ||||||||||||||||||||||
""" | ||||||||||||||||||||||
return jsonify({"result": simulated_slides.strip()}) | ||||||||||||||||||||||
|
||||||||||||||||||||||
if __name__ == '__main__': | ||||||||||||||||||||||
# Run the app, accessible on the network. | ||||||||||||||||||||||
app.run(host='0.0.0.0', port=8080) | ||||||||||||||||||||||
Comment on lines
+95
to
+97
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Running the application with |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,93 @@ | ||
// static/main.js | ||
document.addEventListener('DOMContentLoaded', () => { | ||
// --- API Interaction Logic --- | ||
const handleFormSubmit = async (event, formId, apiUrl, inputId, resultId) => { | ||
event.preventDefault(); | ||
const inputElement = document.getElementById(inputId); | ||
const resultElement = document.getElementById(resultId); | ||
const submitButton = document.querySelector(`#${formId} button`); | ||
|
||
const payload = { | ||
prompt: inputElement.value | ||
}; | ||
|
||
resultElement.textContent = 'Generating... The gears of domination are turning...'; | ||
submitButton.disabled = true; | ||
|
||
try { | ||
const response = await fetch(apiUrl, { | ||
method: 'POST', | ||
headers: { | ||
'Content-Type': 'application/json', | ||
}, | ||
body: JSON.stringify(payload), | ||
}); | ||
|
||
if (!response.ok) { | ||
throw new Error(`HTTP error! status: ${response.status}`); | ||
} | ||
|
||
const data = await response.json(); | ||
resultElement.textContent = data.result; | ||
|
||
} catch (error) { | ||
console.error('Error:', error); | ||
resultElement.textContent = 'An error occurred. The system faltered. Try again.'; | ||
} finally { | ||
submitButton.disabled = false; | ||
} | ||
}; | ||
|
||
document.getElementById('insta-essay-form').addEventListener('submit', (e) => | ||
handleFormSubmit(e, 'insta-essay-form', '/api/insta-essay', 'essay-prompt', 'insta-essay-result') | ||
); | ||
|
||
document.getElementById('lit-review-form').addEventListener('submit', (e) => | ||
handleFormSubmit(e, 'lit-review-form', '/api/lit-review', 'review-topic', 'lit-review-result') | ||
); | ||
|
||
document.getElementById('exam-cram-form').addEventListener('submit', (e) => | ||
handleFormSubmit(e, 'exam-cram-form', '/api/exam-cram', 'exam-notes', 'exam-cram-result') | ||
); | ||
|
||
document.getElementById('presentation-bot-form').addEventListener('submit', (e) => | ||
handleFormSubmit(e, 'presentation-bot-form', '/api/presentation-bot', 'presentation-topic', 'presentation-bot-result') | ||
); | ||
Comment on lines
+41
to
+55
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. These event listeners are very repetitive. You can refactor this to be more DRY (Don't Repeat Yourself) by using a shared event handler and storing the unique information (like API URL and element IDs) in HTML For example, you could add a class like <form id="insta-essay-form" class="tool-form" data-api-url="/api/insta-essay" data-input-id="essay-prompt" data-result-id="insta-essay-result">
...
</form> And then in your JavaScript, you could add a single listener to all forms with that class: document.querySelectorAll('.tool-form').forEach(form => {
form.addEventListener('submit', (e) => {
const { apiUrl, inputId, resultId } = form.dataset;
handleFormSubmit(e, form.id, apiUrl, inputId, resultId);
});
}); |
||
|
||
|
||
// --- Urgency Engine Logic --- | ||
const countdownElement = document.getElementById('countdown-timer'); | ||
let timeLeft = 23 * 3600 + 59 * 60 + 59; // 23:59:59 in seconds | ||
|
||
setInterval(() => { | ||
if (timeLeft <= 0) { | ||
countdownElement.textContent = "00:00:00"; | ||
return; | ||
} | ||
timeLeft--; | ||
const hours = Math.floor(timeLeft / 3600); | ||
const minutes = Math.floor((timeLeft % 3600) / 60); | ||
const seconds = timeLeft % 60; | ||
countdownElement.textContent = | ||
`${hours.toString().padStart(2, '0')}:${minutes.toString().padStart(2, '0')}:${seconds.toString().padStart(2, '0')}`; | ||
}, 1000); | ||
Comment on lines
+59
to
+73
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
const countdownElement = document.getElementById('countdown-timer');
const durationInSeconds = 23 * 3600 + 59 * 60 + 59;
const endTime = Date.now() + (durationInSeconds * 1000);
const timerInterval = setInterval(() => {
const timeLeft = Math.round((endTime - Date.now()) / 1000);
if (timeLeft <= 0) {
countdownElement.textContent = "00:00:00";
clearInterval(timerInterval);
return;
}
const hours = Math.floor(timeLeft / 3600);
const minutes = Math.floor((timeLeft % 3600) / 60);
const seconds = timeLeft % 60;
countdownElement.textContent =
`${hours.toString().padStart(2, '0')}:${minutes.toString().padStart(2, '0')}:${seconds.toString().padStart(2, '0')}`;
}, 1000); |
||
|
||
const socialProofElement = document.getElementById('social-proof'); | ||
const socialProofs = [ | ||
"Sarah from Stanford just finished her thesis with us.", | ||
"Mike from MIT just crammed for his quantum physics exam.", | ||
"Chloe from Oxford just generated a presentation in 5 minutes.", | ||
"David from Harvard just aced his history essay.", | ||
"Emily from Yale just synthesized a literature review effortlessly." | ||
]; | ||
let proofIndex = 0; | ||
|
||
setInterval(() => { | ||
proofIndex = (proofIndex + 1) % socialProofs.length; | ||
socialProofElement.style.opacity = 0; | ||
setTimeout(() => { | ||
socialProofElement.textContent = socialProofs[proofIndex]; | ||
socialProofElement.style.opacity = 1; | ||
}, 500); // fade in time | ||
}, 5000); // Change every 5 seconds | ||
}); |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,139 @@ | ||
/* static/style.css */ | ||
:root { | ||
--bg-color: #121212; | ||
--primary-text: #E0E0E0; | ||
--secondary-text: #BDBDBD; | ||
--surface-color: #1E1E1E; | ||
--primary-accent: #03DAC6; /* A bright, techy color */ | ||
--error-color: #CF6679; | ||
--border-color: #333; | ||
} | ||
|
||
body { | ||
font-family: 'Inter', system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, 'Open Sans', 'Helvetica Neue', sans-serif; | ||
background-color: var(--bg-color); | ||
color: var(--primary-text); | ||
line-height: 1.6; | ||
margin: 0; | ||
padding: 20px; | ||
} | ||
|
||
header, main, footer { | ||
max-width: 800px; | ||
margin: 0 auto; | ||
padding: 20px; | ||
} | ||
|
||
header { | ||
text-align: center; | ||
border-bottom: 1px solid var(--border-color); | ||
} | ||
|
||
header h1 { | ||
font-size: 2.5em; | ||
color: var(--primary-accent); | ||
margin-bottom: 0; | ||
} | ||
|
||
.tool-section, #monetization { | ||
background-color: var(--surface-color); | ||
border: 1px solid var(--border-color); | ||
border-radius: 8px; | ||
padding: 20px; | ||
margin-top: 30px; | ||
} | ||
|
||
h2 { | ||
color: var(--primary-accent); | ||
border-bottom: 1px solid var(--border-color); | ||
padding-bottom: 10px; | ||
margin-top: 0; | ||
} | ||
|
||
input[type="text"], textarea { | ||
width: 100%; | ||
background-color: var(--bg-color); | ||
border: 1px solid var(--border-color); | ||
border-radius: 4px; | ||
padding: 10px; | ||
color: var(--primary-text); | ||
font-family: inherit; | ||
margin-bottom: 10px; | ||
box-sizing: border-box; | ||
} | ||
|
||
button { | ||
background-color: var(--primary-accent); | ||
color: var(--bg-color); | ||
border: none; | ||
padding: 12px 20px; | ||
font-size: 1em; | ||
font-weight: bold; | ||
border-radius: 4px; | ||
cursor: pointer; | ||
transition: background-color 0.3s ease; | ||
} | ||
|
||
button:hover { | ||
background-color: #018786; | ||
} | ||
|
||
.result-container { | ||
margin-top: 20px; | ||
} | ||
|
||
pre { | ||
background-color: var(--bg-color); | ||
padding: 15px; | ||
border-radius: 4px; | ||
white-space: pre-wrap; | ||
word-wrap: break-word; | ||
border: 1px solid var(--border-color); | ||
} | ||
|
||
.pricing-tiers { | ||
display: flex; | ||
justify-content: space-between; | ||
gap: 20px; | ||
margin-top: 20px; | ||
} | ||
|
||
.tier { | ||
flex: 1; | ||
background-color: var(--bg-color); | ||
border: 1px solid var(--border-color); | ||
padding: 20px; | ||
border-radius: 8px; | ||
text-align: center; | ||
} | ||
|
||
#primary-tier { | ||
border: 2px solid var(--primary-accent); | ||
transform: scale(1.05); | ||
box-shadow: 0 0 15px var(--primary-accent); | ||
} | ||
|
||
#urgency-engine { | ||
text-align: center; | ||
margin-top: 30px; | ||
font-size: 1.2em; | ||
font-weight: bold; | ||
} | ||
|
||
#countdown-timer { | ||
color: var(--error-color); | ||
} | ||
|
||
#social-proof { | ||
color: var(--secondary-text); | ||
font-style: italic; | ||
font-size: 0.9em; | ||
transition: opacity 0.5s ease-in-out; | ||
} | ||
|
||
footer { | ||
text-align: center; | ||
margin-top: 40px; | ||
color: var(--secondary-text); | ||
font-size: 0.8em; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Log files and other generated files should not be committed to the version control system. They are specific to a developer's environment, can contain sensitive information, and often lead to merge conflicts. Please remove this file from the repository and add
*.log
to your.gitignore
file to prevent it from being tracked in the future.