Skip to content
Extraits de code Groupes Projets

Comparer les révisions

Les modifications sont affichées comme si la révision source était fusionnée avec la révision cible. En savoir plus sur la comparaison des révisions.

Source

Sélectionner le projet cible
No results found

Cible

Sélectionner le projet cible
  • sbibauw/languagelab
1 résultat
Afficher les modifications
Validations sur la source (8)
......@@ -28,6 +28,7 @@ import config
from security import jwt_cookie, get_jwt_user
from routes.tests import testRouter
from routes.studies import studiesRouter
from routes.chat import chatRouter
websocket_users = defaultdict(lambda: defaultdict(set))
websocket_users_global = defaultdict(set)
......@@ -1057,5 +1058,6 @@ v1Router.include_router(studyRouter)
v1Router.include_router(websocketRouter)
v1Router.include_router(testRouter)
v1Router.include_router(studiesRouter)
v1Router.include_router(chatRouter)
apiRouter.include_router(v1Router)
app.include_router(apiRouter)
from fastapi import APIRouter, HTTPException, Depends
from pydantic import BaseModel
import requests
import os
from dotenv import load_dotenv
load_dotenv()
API_KEY = os.getenv("OPENROUTER_API_KEY")
MODEL_NAME = "mistralai/mistral-small-24b-instruct-2501:free"
API_URL = "https://openrouter.ai/api/v1/chat/completions"
chatRouter = APIRouter(prefix="/chat", tags=["chat"])
class ChatMessage(BaseModel):
session_id: str
role: str
content: str
chat_sessions = {}
@chatRouter.post("/")
async def chat_with_ai(message: ChatMessage):
session_id = message.session_id
user_message = {"role": message.role, "content": message.content}
if session_id not in chat_sessions:
chat_sessions[session_id] = []
chat_sessions[session_id].append(user_message)
headers = {"Authorization": f"Bearer {API_KEY}", "Content-Type": "application/json"}
data = {"model": MODEL_NAME, "messages": chat_sessions[session_id]}
response = requests.post(API_URL, headers=headers, json=data)
if response.status_code == 200:
bot_response = response.json()["choices"][0]["message"]["content"]
chat_sessions[session_id].append({"role": "assistant", "content": bot_response})
return {"response": bot_response}
else:
raise HTTPException(status_code=response.status_code, detail=response.text)
uvicorn[standard]>=0.27.0,<0.28.0
fastapi>=0.110.0,<0.111.0
fastapi_jwt>=0.2.0,<0.3.0
sqlalchemy>=2.0.0,<2.1.0
passlib>=1.7.0,<1.8.0
python-jose>=3.3.0,<3.4.0
python-multipart>=0.0.0,<0.1.0
alembic==1.14.1
annotated-types==0.7.0
anyio==4.7.0
bcrypt==3.2.0
black==24.10.0
certifi==2025.1.31
cffi==1.17.1
charset-normalizer==3.4.1
click==8.1.7
cryptography==44.0.0
ecdsa==0.19.0
fastapi==0.110.3
fastapi-jwt==0.2.0
h11==0.14.0
httptools==0.6.4
idna==3.10
Mako==1.3.9
MarkupSafe==3.0.2
mypy-extensions==1.0.0
packaging==24.2
passlib==1.7.4
pathspec==0.12.1
platformdirs==4.3.6
pyasn1==0.6.1
pycparser==2.22
pydantic==2.10.3
pydantic_core==2.27.1
python-dotenv==1.0.1
python-jose==3.3.0
python-multipart==0.0.19
PyYAML==6.0.2
requests==2.32.3
rsa==4.9
six==1.17.0
sniffio==1.3.1
SQLAlchemy==2.0.36
starlette==0.37.2
typing_extensions==4.12.2
urllib3==2.3.0
uvicorn==0.27.1
uvloop==0.21.0
watchfiles==1.0.3
websockets==14.1
Ce diff est replié.
......@@ -53,6 +53,26 @@ export async function createMessageAPI(
return await response.json();
}
export async function createAIMessageAPI(
fetch: fetchType,
sessionId: string,
content: string
): Promise<any | null> {
const response = await fetch(`/api/chat/`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
session_id: sessionId,
role: 'user',
content: content
})
});
if (!response.ok) return null;
return await response.json();
}
export async function updateMessageAPI(
fetch: fetchType,
id: number,
......
......@@ -62,6 +62,7 @@
rid,
user?.id || null,
typingTest.id,
user?.study_id ?? 0,
position,
downtime,
uptime,
......
......@@ -12,7 +12,8 @@ import {
patchSessionAPI,
removeUserFromSessionAPI,
sendPresenceAPI,
sendTypingAPI
sendTypingAPI,
createAIMessageAPI
} from '$lib/api/sessions';
import Message from './message';
import config from '$lib/config';
......@@ -204,6 +205,8 @@ export default class Session {
replyTo: string | null
): Promise<Message | null> {
const json = await createMessageAPI(fetch, this.id, content, metadata, replyTo);
const ai_message = await createAIMessageAPI(fetch, this.id.toString(), content);
console.log('AI Message: ', ai_message);
if (json == null || json.id == null || json.message_id == null) {
toastAlert('Failed to parse message');
return null;
......
......@@ -162,8 +162,16 @@ export default class User {
return this._tutor_list;
}
get availabilities(): { day: string; start: string; end: string }[] {
return this._availabilities;
get availabilities(): {
avaibility: number;
day: string;
start: string;
end: string;
}[] {
return this._availabilities.map((availability, index) => ({
avaibility: index,
...availability
}));
}
set availabilities(value: { day: string; start: string; end: string }[]) {
......
......@@ -129,6 +129,18 @@
);
}
async function createSoloSession() {
let session = await Session.create();
if (!session) {
console.warn('Failed to create solo session.');
return;
}
contactSessions = [...contactSessions, session].sort(
(a, b) => b.start_time.getTime() - a.start_time.getTime()
);
}
async function searchNickname() {
if (!user || !nickname || !nickname.includes('@')) {
toastWarning('Please enter a valid email address');
......@@ -190,6 +202,16 @@
>
{$t('home.createSession')}
</button>
<button
onclick={(e) => {
e.preventDefault();
createSoloSession();
}}
class="button float-start mr-2"
>
Solo session
</button>
<button
class="button float-start"
class:btn-disabled={!contact || !contact.calcom_link}
......
......@@ -615,7 +615,7 @@
<p class="text-center">
{@html $t('register.continue')}
</p>
<button class="button mt-4 w-full" onclick={() => (current_step = 6)}>
<button class="button mt-4 w-full" onclick={() => (current_step = 8)}>
{$t('register.continueButton')}
</button>
<button class="button mt-4 w-full" onclick={() => (document.location.href = '/')}>
......