Skip to content

Commit

Permalink
feat: init essential conversation data access for student
Browse files Browse the repository at this point in the history
  • Loading branch information
TakalaWang committed Nov 27, 2024
1 parent a0a036b commit 3618c8a
Show file tree
Hide file tree
Showing 6 changed files with 120 additions and 308 deletions.
2 changes: 0 additions & 2 deletions src/routes/session/[id]/+page.server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -108,8 +108,6 @@ export const actions = {
status: 'active',
stage: 'individual'
});

throw redirect(303, `/session/${sessionId}/status`);
} catch (error) {
console.error('Error starting individual stage:', error);
return fail(500, { error: true });
Expand Down
6 changes: 4 additions & 2 deletions src/routes/session/[id]/+page.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,7 @@
import { goto } from '$app/navigation';
import type { Session } from '$lib/schema/session';
import type { Readable } from 'svelte/store';
import { create } from 'qrcode';
import { on } from 'svelte/events';
import QRCode from '$lib/components/QRCode.svelte';
let { data } = $props();
let session = $state(getContext<Readable<Session>>('session'));
Expand Down Expand Up @@ -180,11 +179,14 @@
<button
type="submit"
class="inline-flex items-center gap-2 rounded-lg bg-blue-600 px-4 py-2 text-white hover:bg-blue-700"
onclick={startIndividualStage}
>
<Play size={20} />
開始討論
</button>
</form>
<!-- show QRcode by page id -->
<QRCode value={$page.params.id} />
{:else if $session.stage === 'individual'}
<button
class="inline-flex items-center gap-2 rounded-lg bg-blue-600 px-4 py-2 text-white hover:bg-blue-700"
Expand Down
206 changes: 84 additions & 122 deletions src/routes/session/[id]/participant/+page.server.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,8 @@
import { env } from '$env/dynamic/private';
import { SessionSchema } from '$lib/schema/session';
import { adminDb } from '$lib/server/firebase';
import { chatWithLLMByDocs } from '$lib/server/llm';
import { parsePdf2Text } from '$lib/server/parse';
import { transcribe } from '$lib/stt/core';
import { error, redirect } from '@sveltejs/kit';
import type { z } from 'zod';
import type { Actions, PageServerLoad } from './[conversation_id]/$types';
import type { Actions, PageServerLoad } from './$types';

export const load: PageServerLoad = async ({ params, locals }) => {
if (!locals.user) {
Expand All @@ -15,13 +11,23 @@ export const load: PageServerLoad = async ({ params, locals }) => {

const sessionRef = adminDb.collection('sessions').doc(params.id);
const session = (await sessionRef.get()).data() as z.infer<typeof SessionSchema>;
if (session.stage == '')
if (!session) {
throw error(404, 'Session not found');
}

if (!session) {
throw error(404, 'Session not found');
}
if (!(locals.user.uid in session.participants)) {
throw error(403, 'Not a participant in this session');
throw redirect(303, '/session');
}

if (session.stage === 'individual') {
const conversationRef = adminDb.collection('conversation').doc();
await conversationRef.set({
sessionId: params.id,
userId: locals.user.uid,
role: 'user',
content: '',
timestamp: new Date().toISOString()
});
throw redirect(303, `/session/${params.id}/conversation/${conversationRef.id}`);
}

return {
Expand All @@ -30,120 +36,76 @@ export const load: PageServerLoad = async ({ params, locals }) => {
};

export const actions = {
// createGroup: async ({ request, locals, params }) => {
// startIndividualStage: async ({ locals, params }) => {
// const sessionId = params.id;
// const sessionRef = adminDb.collection('sessions').doc(sessionId);
// const sessionData = (await sessionRef.get()).data() as FirestoreSession;
// if (sessionData.hostId != locals.user?.uid) {
// throw redirect(401, 'Unauthorized');
// }
// const resourcesTexts = [];
// // parse pdf files to text
// for (const resourceId of sessionData.resourceIds) {
// const resourceRef = adminDb.collection('resources').doc(resourceId);
// const resourceData = (await resourceRef.get()).data();
// const text = await parsePdf2Text(resourceData?.fileId);
// resourcesTexts.push(text);
// }
// // create conversation for each participants
// for (const participantId in sessionData.participants) {
// const individualDiscussionRef = adminDb.collection('individualDiscussion').doc();
// await individualDiscussionRef.set({
// userId: participantId,
// sessionId: sessionId,
// groupId: sessionData.participants[participantId].groupId,
// goal: sessionData.goal,
// subQuestions: sessionData.subQuestions,
// resourcesTexts: resourcesTexts,
// history: [],
// summary: ''
// });
// }
// // set session stage to individual
// await sessionRef.update({ stage: 'individual' });
// return { success: true };
// },
// sendConversation: async ({ request, locals, params }) => {
// if (!locals.user) {
// throw error(401, 'Unauthorized');
// }

// const data = await request.formData();
// const groupName = data.get('groupName')?.toString();

// if (!groupName) {
// return fail(400, { missing: true });
// const { speech } = await request.json();
// const userId = locals.user.uid;
// const sessionId = params.id;
// const fileId = 'Unknown file id'; // TODO: get file id from the file upload
// const text = await transcribe(speech, env.HUGGINGFACE_TOKEN);
// const individualDiscussionRef = adminDb
// .collection('individualDiscussion')
// .where('userId', '==', userId)
// .where('sessionId', '==', sessionId);
// const individualDiscussionData = (
// await individualDiscussionRef.get()
// ).docs[0].data() as FirestoreIndividualDiscussion;
// if (!individualDiscussionData) {
// throw error(404, 'Individual discussion not found');
// }

// const sessionRef = adminDb.collection('sessions').doc(params.id);
// const groupId = crypto.randomUUID();

// await sessionRef.update({
// [`groups.${groupId}`]: {
// name: groupName,
// leaderId: locals.user.uid,
// members: {
// [locals.user.uid]: {
// name: locals.user.name,
// joinedAt: new Date()
// }
// }
// }
// const { history, goal, subQuestions, resourcesTexts } =
// convertFirestoreIndividualDiscussion(individualDiscussionData);
// history.push({
// role: 'user',
// fileId: fileId,
// content: text,
// timestamp: new Date().toISOString()
// });

// return { success: true, groupId };
// },

startIndividualStage: async ({ locals, params }) => {
const sessionId = params.id;
const sessionRef = adminDb.collection('sessions').doc(sessionId);
const sessionData = (await sessionRef.get()).data() as FirestoreSession;
if (sessionData.hostId != locals.user?.uid) {
throw redirect(401, 'Unauthorized');
}

const resourcesTexts = [];
// parse pdf files to text
for (const resourceId of sessionData.resourceIds) {
const resourceRef = adminDb.collection('resources').doc(resourceId);
const resourceData = (await resourceRef.get()).data();
const text = await parsePdf2Text(resourceData?.fileId);
resourcesTexts.push(text);
}

// create conversation for each participants
for (const participantId in sessionData.participants) {
const individualDiscussionRef = adminDb.collection('individualDiscussion').doc();
await individualDiscussionRef.set({
userId: participantId,
sessionId: sessionId,
groupId: sessionData.participants[participantId].groupId,
goal: sessionData.goal,
subQuestions: sessionData.subQuestions,
resourcesTexts: resourcesTexts,
history: [],
summary: ''
});
}

// set session stage to individual
await sessionRef.update({ stage: 'individual' });

return { success: true };
},

sendConversation: async ({ request, locals, params }) => {
if (!locals.user) {
throw error(401, 'Unauthorized');
}
const { speech } = await request.json();
const userId = locals.user.uid;
const sessionId = params.id;

const fileId = 'Unknown file id'; // TODO: get file id from the file upload
const text = await transcribe(speech, env.HUGGINGFACE_TOKEN);

const individualDiscussionRef = adminDb
.collection('individualDiscussion')
.where('userId', '==', userId)
.where('sessionId', '==', sessionId);
const individualDiscussionData = (
await individualDiscussionRef.get()
).docs[0].data() as FirestoreIndividualDiscussion;

if (!individualDiscussionData) {
throw error(404, 'Individual discussion not found');
}

const { history, goal, subQuestions, resourcesTexts } =
convertFirestoreIndividualDiscussion(individualDiscussionData);

history.push({
role: 'user',
fileId: fileId,
content: text,
timestamp: new Date().toISOString()
});

const response = await chatWithLLMByDocs(history, goal, subQuestions, resourcesTexts);
if (!response.success) {
throw error(500, response.error);
}

history.push({
role: 'user',
fileId: null,
content: response.message,
timestamp: new Date().toISOString()
});

return { success: true };
}
// const response = await chatWithLLMByDocs(history, goal, subQuestions, resourcesTexts);
// if (!response.success) {
// throw error(500, response.error);
// }
// history.push({
// role: 'user',
// fileId: null,
// content: response.message,
// timestamp: new Date().toISOString()
// });
// return { success: true };
// }
} satisfies Actions;
Loading

0 comments on commit 3618c8a

Please sign in to comment.