Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
75 commits
Select commit Hold shift + click to select a range
1884a12
generate the flashcard
leonorlyn Jun 30, 2025
73a275b
add color and size custom
leonorlyn Jul 1, 2025
a6ea323
add layout/type
leonorlyn Jul 1, 2025
18e68ad
reorg: add Cards, Spinner, and setup for AI component
KY233466 Jul 1, 2025
9c6147a
setup for AI environment
KY233466 Jul 1, 2025
e61e780
setup for AI component
KY233466 Jul 1, 2025
f11d1f8
setup for AI component
KY233466 Jul 1, 2025
61ad7e3
AI integeration
KY233466 Jul 1, 2025
e7dccd6
attempt at pdf
KY233466 Jul 1, 2025
bc6db52
add templates
CuichanWu Jul 2, 2025
c4858bf
border radius did not apply to template1
CuichanWu Jul 2, 2025
a69ce26
adjust multiline text to adjust the size
leonorlyn Jul 2, 2025
e7b9e1a
add layout/type back
leonorlyn Jul 2, 2025
afd6848
fix card and fileImport
KY233466 Jul 2, 2025
bc443e7
add parse ppt
KY233466 Jul 2, 2025
d294aea
add parse ppt
KY233466 Jul 2, 2025
8e379d6
add image processing
KY233466 Jul 2, 2025
9bf9d26
error handling in fileImport's fetch
KY233466 Jul 2, 2025
f416c1d
add border radius
CuichanWu Jul 3, 2025
e93b1d7
move extract text to frontend code to cut cost for backend cloud depl…
KY233466 Jul 7, 2025
0340399
restructure a bit for ui change
KY233466 Jul 7, 2025
88389af
change styles and fix textarea
KY233466 Jul 7, 2025
852c89c
change Template position
KY233466 Jul 7, 2025
9c554e9
change ui and manifest
KY233466 Jul 8, 2025
65b80ea
refractor upload
KY233466 Jul 8, 2025
56a57ac
change upload flow
KY233466 Jul 9, 2025
95adb25
refractor settings
KY233466 Jul 9, 2025
1898475
add svg and paginationcomponent
CuichanWu Jul 9, 2025
7c2811c
add loading page
KY233466 Jul 9, 2025
614e68a
add loading page
KY233466 Jul 9, 2025
6c3ccb6
ui change
KY233466 Jul 9, 2025
0255d5f
refractor code and add Next btn to Upload
KY233466 Jul 10, 2025
b9519bb
update styles
CuichanWu Jul 10, 2025
d0f91a9
clean code
CuichanWu Jul 10, 2025
274b991
change generate function
KY233466 Jul 11, 2025
31806ee
more change to generate
KY233466 Jul 11, 2025
8fe8fb6
update some styles on template page
CuichanWu Jul 12, 2025
8a945a7
change card size selector style
CuichanWu Jul 12, 2025
fe06df5
adjust the card and add some fake card size
CuichanWu Jul 12, 2025
b51b1fa
update settings ui
leonorlyn Jul 12, 2025
ffcab05
fix flashcard ui
KY233466 Jul 12, 2025
bb6664c
fix tab selection
KY233466 Jul 12, 2025
692d6aa
prepare for private link
KY233466 Jul 12, 2025
f678d47
update settings details
leonorlyn Jul 12, 2025
6222da5
add diff length opt
leonorlyn Jul 12, 2025
47e26c8
add template picture'
CuichanWu Jul 12, 2025
275dd46
Merge branch 'main' of https://github.com/KY233466/FlashCard
CuichanWu Jul 12, 2025
b94644f
adjust styles to reduce width
CuichanWu Jul 12, 2025
1e63a1a
prepare for private link
KY233466 Jul 12, 2025
a1429d1
clean up unused files
KY233466 Jul 12, 2025
f688dcf
reapply the api section in settings
leonorlyn Jul 12, 2025
8764228
update generate method with comments
leonorlyn Jul 12, 2025
4a6e81a
add babel/cli
KY233466 Jul 12, 2025
ecf4826
Merge branch 'main' of https://github.com/KY233466/FlashCard
KY233466 Jul 12, 2025
b312221
prepare for private link
KY233466 Jul 13, 2025
3981198
adjust card size
CuichanWu Jul 13, 2025
6531ce7
remove audience && add question/answer length
leonorlyn Jul 13, 2025
8a5f0fe
generate private link
KY233466 Jul 13, 2025
1d908c1
Merge branch 'main' of https://github.com/KY233466/FlashCard
KY233466 Jul 13, 2025
5dc9bf9
Merge branch 'main' of https://github.com/KY233466/FlashCard
CuichanWu Jul 13, 2025
6ea9605
change webpack
KY233466 Jul 13, 2025
0bfd691
Merge branch 'main' of https://github.com/KY233466/FlashCard
CuichanWu Jul 13, 2025
422a9a5
one or two sided control
CuichanWu Jul 13, 2025
4ae5169
add horizontal and vertical function
CuichanWu Jul 13, 2025
95af8da
safely get editor context
leonorlyn Jul 13, 2025
0c03de6
change backend structure
KY233466 Jul 13, 2025
3fd8e06
resolve package problem
KY233466 Jul 13, 2025
157aee3
template1 qa two side keeps the same color
CuichanWu Jul 13, 2025
8d84481
template 1 doesn't change font size
CuichanWu Jul 13, 2025
b6756fc
update template2 and template4 styles
CuichanWu Jul 13, 2025
f263a47
add a basic auto artboard seperation
leonorlyn Jul 14, 2025
f7ed9b3
createFlashcards clear pages and add nessesary pages
KY233466 Jul 14, 2025
92bf52d
fix clear page and artboards
KY233466 Jul 14, 2025
58220e5
delete experiment code
KY233466 Jul 14, 2025
0ead6e1
fig constant && fix logic for artboard
leonorlyn Jul 14, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .babelrc
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
{
"presets": ["@babel/preset-env", "@babel/preset-react"]
}
"presets": ["@babel/preset-react"]
}
33 changes: 32 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,35 @@
dist/
node_modules/
yarn.lock
package-lock.json
package-lock.json

# Logs
logs
*.log
npm-debug.log*
yarn-debug.log*
yarn-error.log*
pnpm-debug.log*
lerna-debug.log*

node_modules
dist
dist-ssr
*.local
.env
.venv
venv

# Editor directories and files
.vscode/*
!.vscode/extensions.json
.idea
.DS_Store
*.suo
*.ntvs*
*.njsproj
*.sln
*.sw?

__pycache__
__pycache__/
218 changes: 130 additions & 88 deletions AI/app.py
Original file line number Diff line number Diff line change
@@ -1,103 +1,145 @@
from typing import Any
import logging
from flask import Flask, request, jsonify, current_app, send_from_directory
from flask_cors import CORS
from llmproxy import generate
import sys
from pymongo import MongoClient
import bcrypt
from __future__ import annotations

import sys, json, logging, requests
from typing import List, Dict, Any, Union
from dotenv import load_dotenv
from flask import Flask, request, jsonify, current_app
from flask_cors import CORS
import os
sys.stdout.reconfigure(encoding='utf-8')

app = Flask(__name__, static_folder='public', static_url_path='')
CORS(app, supports_credentials=True, origins=["https://localhost:5241, https://localhost:4000", "https://localhost:3000"])

@app.route('/api/document', methods=['POST'])
def respond_document():
data = request.get_json()

document = data.get("attachment", "").strip()
load_dotenv()
api_key = os.getenv('api_key')
end_point = os.getenv('end_point')

if not document:
return jsonify({"response": "Please provide a document"}), 400
print(f"API Key: {api_key}")
print(f"Database URL: {end_point}")

prompt = f""""""


content = ""
sys.stdout.reconfigure(encoding='utf-8')

app = Flask(__name__, static_folder='public', static_url_path='')
CORS(app, supports_credentials=True, origins=[
"https://localhost:5241",
"https://localhost:4000",
"https://localhost:3000"
])

log = logging.getLogger("pdf_logger")

def _safe_get_json(raw: Union[Dict[str, Any], str], key: str) -> dict:
payload = raw.get(key, "") if isinstance(raw, dict) else ""
if isinstance(payload, dict):
return payload
try:
final_response = generate(
model='4o-mini',
system=prompt,
query=content,
temperature=0.0,
lastk=0,
session_id='rew'
)

cleaned = payload.strip().removeprefix("```json").removesuffix("```").strip()
return json.loads(cleaned)
except Exception as e:
current_app.logger.error("Error in generate: %s", str(e))
return jsonify({"response": "Internal error during extraction."}), 500

return jsonify({"final_response": final_response})

@app.route('/api/image', methods=['POST'])
def respond_image():
data = request.get_json()

document = data.get("attachment", "").strip()

if not document:
return jsonify({"response": "Please provide an image"}), 400
current_app.logger.error("Failed JSON parse: %s", e)
raise ValueError("Invalid JSON in LLM output")

def _llm_generate(md_text: str, prompt: str) -> dict:
raw = generate(
model="4o-mini",
system=prompt,
query=md_text[:8000], # truncate for cost/speed safety
temperature=0.3,
lastk=0,
session_id="ai-question-gen",
)

return _safe_get_json(raw, "response")

def _cards_from_text(
text: str, questionPrompt: str, answerPrompt: str
) -> List[Dict[str, str]]:
questions = _llm_generate(text, questionPrompt).get("questions", [])
print(f"questions: {questions}")

cards = [{"question": q, "answer": ""} for q in questions]

user_parts = []
user_parts.append("### CONTEXT\n" + text[:8000])
user_parts.append("### CONTEXT END\n" + "### QUESTIONS\n".join(f"{i+1}. {q}" for i, q in enumerate(questions)))
query = "\n\n".join(user_parts)

answers = _llm_generate(query, answerPrompt).get("answers", [])

print(f"answers: {answers}")

for i, a in enumerate(answers):
cards[i]["answer"] = a.strip()

return cards

@app.route("/api/document", methods=["POST"])
def respond_document():
data = request.get_json(force=True, silent=True) or {}
raw_text = str(data.get("text", "")).strip()
questionPrompt = str(data.get("questionPrompt", ""))
answerPrompt = str(data.get("answerPrompt", ""))

prompt = f""""""
# 详细的调试日志
current_app.logger.info(f"=== API Request Debug ===")
current_app.logger.info(f"Raw data received: {data}")
current_app.logger.info(f"Question Prompt: {questionPrompt}")
current_app.logger.info(f"answerPrompt: {answerPrompt}")

content = ""
if not raw_text:
return jsonify({"response": "Please provide non-empty 'text'."}), 400

try:
final_response = generate(
model='4o-mini',
system=prompt,
query=content,
temperature=0.0,
lastk=0,
session_id='rew'
)

cards = _cards_from_text(raw_text, questionPrompt, answerPrompt)
current_app.logger.info(f"Final cards generated: {len(cards)}")
current_app.logger.info(f"Card questions: {[card.get('question', '') for card in cards]}")
except Exception as e:
current_app.logger.error("Error in generate: %s", str(e))
return jsonify({"response": "Internal error during extraction."}), 500

return jsonify({"final_response": final_response})


@app.route('/api/text', methods=['POST'])
def respond_text():
data = request.get_json()

text = data.get("text", "").strip()

if not text:
return jsonify({"response": "Please provide text"}), 400

prompt = f""""""

content = ""
current_app.logger.error("Error in /api/document: %s", e)
return jsonify({"response": "Failed to generate flash cards."}), 500

return jsonify({"cards": cards})

def generate(
model: str,
system: str,
query: str,
temperature: float | None = None,
lastk: int | None = None,
session_id: str | None = None,
rag_threshold: float | None = 0.5,
rag_usage: bool | None = False,
rag_k: int | None = 0
):
headers = {
'x-api-key': api_key
}

request = {
'model': model,
'system': system,
'query': query,
'temperature': temperature,
'lastk': lastk,
'session_id': session_id,
'rag_threshold': rag_threshold,
'rag_usage': rag_usage,
'rag_k': rag_k
}

print(f"request: {request}")

msg = None

try:
final_response = generate(
model='4o-mini',
system=prompt,
query=content,
temperature=0.0,
lastk=0,
session_id='rew'
)

except Exception as e:
current_app.logger.error("Error in generate : %s", str(e))
return jsonify({"response": "Internal error during extraction."}), 500

return jsonify({"final_response": final_response})
response = requests.post(end_point, headers=headers, json=request)

print(f"response: {response}")

if response.status_code == 200:
res = json.loads(response.text)
msg = {'response': res['result'], 'rag_context': res['rag_context']}
else:
msg = f"Error: Received response code {response.status_code}"
except requests.exceptions.RequestException as e:
msg = f"An error occurred: {e}"
return msg

if __name__ == "__main__":
app.run(ssl_context=("dev.crt", "dev.key"), host="127.0.0.1", port=5001)
Loading