@speakableio/core 1.0.12 → 1.0.14

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -772,6 +772,11 @@ interface PageScore {
772
772
  hint?: string[];
773
773
  reviewed?: boolean;
774
774
  error?: ('feedback_error' | 'transcript_error' | 'summary_error' | 'audio_upload_error' | 'unknown' | null)[];
775
+ stagedResponse?: {
776
+ audio?: string | null;
777
+ fileName?: string | null;
778
+ transcript?: string | null;
779
+ } | null;
775
780
  }
776
781
 
777
782
  declare enum AssignmentAnalyticsType {
@@ -993,7 +998,9 @@ declare function useUpdateCardScore({ isAssignment, activityId, userId, cardIds,
993
998
  }, Error, {
994
999
  cardId: string;
995
1000
  cardScore: PageScore;
996
- }, void>;
1001
+ }, {
1002
+ previousData: Score | undefined;
1003
+ }>;
997
1004
  };
998
1005
  declare function useClearScore(): {
999
1006
  mutationClearScore: _tanstack_react_query.UseMutationResult<{
@@ -1007,6 +1014,18 @@ declare function useClearScore(): {
1007
1014
  activityId: string;
1008
1015
  }, unknown>;
1009
1016
  };
1017
+ declare function useClearScoreV2(): {
1018
+ mutationClearScore: _tanstack_react_query.UseMutationResult<{
1019
+ update: Partial<Score>;
1020
+ activityId: string;
1021
+ }, Error, {
1022
+ isAssignment: boolean;
1023
+ cardId: string;
1024
+ cardScores: PageScore;
1025
+ userId: string;
1026
+ activityId: string;
1027
+ }, unknown>;
1028
+ };
1010
1029
  declare function useSubmitAssignmentScore({ onAssignmentSubmitted, studentName, }: {
1011
1030
  onAssignmentSubmitted: (assignmentId: string) => void;
1012
1031
  studentName: string;
@@ -2760,7 +2779,7 @@ declare const useBaseOpenAI: ({ onTranscriptSuccess, onTranscriptError, onComple
2760
2779
  url: string;
2761
2780
  fileName: string;
2762
2781
  }>;
2763
- uploadAudioAndGetTranscript: (audio: string, language: string) => Promise<{
2782
+ uploadAudioAndGetTranscript: (audio: string, language: string, pagePrompt: string | null) => Promise<{
2764
2783
  transcript: string;
2765
2784
  audioUrl: string;
2766
2785
  }>;
@@ -2773,19 +2792,20 @@ declare const useBaseOpenAI: ({ onTranscriptSuccess, onTranscriptError, onComple
2773
2792
  url: string;
2774
2793
  fileName: string;
2775
2794
  }>;
2776
- uploadAudioAndGetTranscript: (audio: string, language: string) => Promise<{
2795
+ uploadAudioAndGetTranscript: (audio: string, language: string, pagePrompt: string | null) => Promise<{
2777
2796
  transcript: string;
2778
2797
  audioUrl: string;
2779
2798
  }>;
2780
- getTranscript: (audioUrl: string, language: string) => Promise<string>;
2799
+ getTranscript: (audioUrl: string, language: string, prompt?: string) => Promise<any>;
2781
2800
  getFreeResponseCompletion: (messages: string[], isFreeResponse: boolean, feedbackLanguage: string, gradingStandard?: string) => Promise<any>;
2782
- getFeedback: ({ cardId, language, writtenResponse, audio, autoGrade, file, }: {
2801
+ getFeedback: ({ cardId, language, writtenResponse, audio, autoGrade, file, pagePrompt, }: {
2783
2802
  cardId: string;
2784
2803
  language: string;
2785
2804
  writtenResponse: string | null;
2786
2805
  audio: string | null;
2787
2806
  autoGrade: boolean;
2788
2807
  file: string | null;
2808
+ pagePrompt: string | null;
2789
2809
  }) => Promise<{
2790
2810
  noFeedbackAvailable: boolean;
2791
2811
  success: boolean;
@@ -3242,4 +3262,4 @@ declare const createFsClientWeb: ({ db, httpsCallable, logEvent }: FsClientParam
3242
3262
  };
3243
3263
  };
3244
3264
 
3245
- export { ActivityPageType, type Assignment, type AssignmentAnalyticsType$1 as AssignmentAnalyticsType, type AssignmentWithId, BASE_MULTIPLE_CHOICE_FIELD_VALUES, BASE_REPEAT_FIELD_VALUES, BASE_RESPOND_FIELD_VALUES, type CreditContract, FeedbackTypesCard, FsCtx, type InstitutionSubscription, LENIENCY_OPTIONS, LeniencyCard, MULTIPLE_CHOICE_PAGE_ACTIVITY_TYPES, type Organization, type OrganizationAccess, type PageActivity, type PageActivityWithId, type PageScore, REPEAT_PAGE_ACTIVITY_TYPES, RESPOND_AUDIO_PAGE_ACTIVITY_TYPES, RESPOND_PAGE_ACTIVITY_TYPES, RESPOND_WRITE_PAGE_ACTIVITY_TYPES, type RefsCardsFiresotre, type RefsSetsFirestore, SPEAKABLE_NOTIFICATIONS, STUDENT_LEVELS_OPTIONS, type Score, type ScoreWithId, type Set, type SetWithId, type SpeakableNotificationType, SpeakableNotificationTypes, SpeakableProvider, VerificationCardStatus, assignmentQueryKeys, cardsQueryKeys, checkIsMCPage, checkIsMediaPage, checkIsRepeatPage, checkIsRespondAudioPage, checkIsRespondPage, checkIsRespondWrittenPage, checkIsShortAnswerPage, checkTypePageActivity, cleanString, createAssignmentRepo, createCardRepo, createFsClientWeb as createFsClient, createSetRepo, creditQueryKeys, debounce, getCardFromCache, getLabelPage, getPagePrompt, getPhraseLength, getRespondCardTool, getSetFromCache, getTotalCompletedCards, getWordHash, purify, refsCardsFiresotre, refsSetsFirestore, scoreQueryKeys, setsQueryKeys, updateCardInCache, updateSetInCache, useActivity, useActivityFeedbackAccess, useAssignment, useBaseOpenAI, useCards, useClearScore, useCreateCard, useCreateCards, useCreateNotification, useGetCard, useOrganizationAccess, useScore, useSet, useSpeakableApi, useSubmitAssignmentScore, useSubmitPracticeScore, useUpdateCardScore, useUpdateScore, useUpdateStudentVocab, useUserCredits };
3265
+ export { ActivityPageType, type Assignment, type AssignmentAnalyticsType$1 as AssignmentAnalyticsType, type AssignmentWithId, BASE_MULTIPLE_CHOICE_FIELD_VALUES, BASE_REPEAT_FIELD_VALUES, BASE_RESPOND_FIELD_VALUES, type CreditContract, FeedbackTypesCard, FsCtx, type InstitutionSubscription, LENIENCY_OPTIONS, LeniencyCard, MULTIPLE_CHOICE_PAGE_ACTIVITY_TYPES, type Organization, type OrganizationAccess, type PageActivity, type PageActivityWithId, type PageScore, REPEAT_PAGE_ACTIVITY_TYPES, RESPOND_AUDIO_PAGE_ACTIVITY_TYPES, RESPOND_PAGE_ACTIVITY_TYPES, RESPOND_WRITE_PAGE_ACTIVITY_TYPES, type RefsCardsFiresotre, type RefsSetsFirestore, SPEAKABLE_NOTIFICATIONS, STUDENT_LEVELS_OPTIONS, type Score, type ScoreWithId, type Set, type SetWithId, type SpeakableNotificationType, SpeakableNotificationTypes, SpeakableProvider, VerificationCardStatus, assignmentQueryKeys, cardsQueryKeys, checkIsMCPage, checkIsMediaPage, checkIsRepeatPage, checkIsRespondAudioPage, checkIsRespondPage, checkIsRespondWrittenPage, checkIsShortAnswerPage, checkTypePageActivity, cleanString, createAssignmentRepo, createCardRepo, createFsClientWeb as createFsClient, createSetRepo, creditQueryKeys, debounce, getCardFromCache, getLabelPage, getPagePrompt, getPhraseLength, getRespondCardTool, getSetFromCache, getTotalCompletedCards, getWordHash, purify, refsCardsFiresotre, refsSetsFirestore, scoreQueryKeys, setsQueryKeys, updateCardInCache, updateSetInCache, useActivity, useActivityFeedbackAccess, useAssignment, useBaseOpenAI, useCards, useClearScore, useClearScoreV2, useCreateCard, useCreateCards, useCreateNotification, useGetCard, useOrganizationAccess, useScore, useSet, useSpeakableApi, useSubmitAssignmentScore, useSubmitPracticeScore, useUpdateCardScore, useUpdateScore, useUpdateStudentVocab, useUserCredits };
package/dist/index.web.js CHANGED
@@ -47,6 +47,8 @@ function withErrorHandler(fn, serviceName) {
47
47
  try {
48
48
  return await fn(...args);
49
49
  } catch (error) {
50
+ console.error(`Service ${serviceName} failed with args:`, args);
51
+ console.error("Error details:", error);
50
52
  if (error instanceof Error && "code" in error) {
51
53
  const firebaseError = error;
52
54
  throw new ServiceError(
@@ -1143,6 +1145,39 @@ async function clearScore(params) {
1143
1145
  activityId: params.activityId
1144
1146
  };
1145
1147
  }
1148
+ async function clearScoreV2(params) {
1149
+ var _a, _b, _c, _d, _e;
1150
+ const update = {
1151
+ [`cards.${params.cardId}`]: {
1152
+ ...params.cardScores,
1153
+ attempts: ((_a = params.cardScores.attempts) != null ? _a : 1) + 1,
1154
+ correct: (_b = params.cardScores.correct) != null ? _b : 0,
1155
+ history: [
1156
+ {
1157
+ ...params.cardScores,
1158
+ attempts: (_c = params.cardScores.attempts) != null ? _c : 1,
1159
+ correct: (_d = params.cardScores.correct) != null ? _d : 0,
1160
+ retryTime: dayjs3().format("YYYY-MM-DD HH:mm:ss"),
1161
+ history: null
1162
+ },
1163
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
1164
+ ...(_e = params.cardScores.history) != null ? _e : []
1165
+ ]
1166
+ }
1167
+ };
1168
+ const path = params.isAssignment ? refsAssignmentFiresotre.assignmentScores({
1169
+ id: params.activityId,
1170
+ userId: params.userId
1171
+ }) : refsScoresPractice.practiceScores({
1172
+ setId: params.activityId,
1173
+ userId: params.userId
1174
+ });
1175
+ await api.updateDoc(path, update);
1176
+ return {
1177
+ update,
1178
+ activityId: params.activityId
1179
+ };
1180
+ }
1146
1181
 
1147
1182
  // src/domains/assignment/services/submit-assignment-score.service.ts
1148
1183
  import dayjs4 from "dayjs";
@@ -1255,7 +1290,7 @@ function useScore({
1255
1290
  enabled
1256
1291
  });
1257
1292
  }
1258
- var debounceUpdateScore = debounce(updateScore, 1e3);
1293
+ var debounceUpdateScore = debounce(updateScore, 500);
1259
1294
  function useUpdateScore() {
1260
1295
  const { queryClient } = useSpeakableApi();
1261
1296
  const mutation = useMutation({
@@ -1314,6 +1349,7 @@ function useUpdateCardScore({
1314
1349
  return { cardId, scoresUpdated: newScoreUpdated };
1315
1350
  },
1316
1351
  onMutate: ({ cardId, cardScore }) => {
1352
+ const previousData = queryClient.getQueryData(queryKey);
1317
1353
  queryClient.setQueryData(queryKey, (previousScore) => {
1318
1354
  const updates = handleOptimisticScore({
1319
1355
  score: previousScore,
@@ -1327,14 +1363,18 @@ function useUpdateCardScore({
1327
1363
  ...updates
1328
1364
  };
1329
1365
  });
1366
+ return { previousData };
1330
1367
  },
1331
- // eslint-disable-next-line no-unused-vars
1332
- onError: (error) => {
1333
- console.log(error.message);
1334
- const previousData = queryClient.getQueryData(queryKey);
1335
- if (previousData) {
1336
- queryClient.setQueryData(queryKey, previousData);
1368
+ onError: (error, variables, context) => {
1369
+ console.log("Error updating card score:", error.message);
1370
+ if (context == null ? void 0 : context.previousData) {
1371
+ queryClient.setQueryData(queryKey, context.previousData);
1337
1372
  }
1373
+ },
1374
+ onSettled: () => {
1375
+ queryClient.invalidateQueries({
1376
+ queryKey
1377
+ });
1338
1378
  }
1339
1379
  });
1340
1380
  return {
@@ -1400,6 +1440,27 @@ function useClearScore() {
1400
1440
  const { queryClient } = useSpeakableApi();
1401
1441
  const mutation = useMutation({
1402
1442
  mutationFn: clearScore,
1443
+ onError: (error) => {
1444
+ console.log("Error clearing score:", error.message);
1445
+ },
1446
+ onSettled: (result) => {
1447
+ var _a;
1448
+ queryClient.invalidateQueries({
1449
+ queryKey: scoreQueryKeys.byId((_a = result == null ? void 0 : result.activityId) != null ? _a : "")
1450
+ });
1451
+ }
1452
+ });
1453
+ return {
1454
+ mutationClearScore: mutation
1455
+ };
1456
+ }
1457
+ function useClearScoreV2() {
1458
+ const { queryClient } = useSpeakableApi();
1459
+ const mutation = useMutation({
1460
+ mutationFn: clearScoreV2,
1461
+ onError: (error) => {
1462
+ console.log("Error clearing score V2:", error.message);
1463
+ },
1403
1464
  onSettled: (result) => {
1404
1465
  var _a;
1405
1466
  queryClient.invalidateQueries({
@@ -2992,21 +3053,38 @@ var useBaseOpenAI = ({
2992
3053
  const { data: feedbackAccess } = useActivityFeedbackAccess({
2993
3054
  aiEnabled
2994
3055
  });
2995
- const getTranscript = async (audioUrl, language) => {
2996
- var _a, _b;
3056
+ const getTranscript = async (audioUrl, language, prompt) => {
3057
+ var _a, _b, _c, _d;
3058
+ const getGeminiTranscript = (_b = (_a = api).httpsCallable) == null ? void 0 : _b.call(_a, "getGeminiTranscript");
3059
+ const getAssemblyAITranscript = (_d = (_c = api).httpsCallable) == null ? void 0 : _d.call(_c, "transcribeAssemblyAIAudio");
3060
+ try {
3061
+ const { data } = await (getGeminiTranscript == null ? void 0 : getGeminiTranscript({
3062
+ audioUrl,
3063
+ targetLanguage: language,
3064
+ prompt: prompt || ""
3065
+ }));
3066
+ const transcript = data.transcript;
3067
+ if (transcript) {
3068
+ return transcript;
3069
+ }
3070
+ } catch (error) {
3071
+ console.log("Gemini transcript failed, trying AssemblyAI fallback:", error);
3072
+ }
2997
3073
  try {
2998
- const getAssemblyAITranscript = (_b = (_a = api).httpsCallable) == null ? void 0 : _b.call(_a, "transcribeAssemblyAIAudio");
2999
3074
  const response = await (getAssemblyAITranscript == null ? void 0 : getAssemblyAITranscript({
3000
3075
  audioUrl,
3001
3076
  language
3002
3077
  }));
3003
3078
  const transcript = response == null ? void 0 : response.data;
3004
- return transcript;
3079
+ if (transcript) {
3080
+ return transcript;
3081
+ }
3082
+ throw new Error("Both transcript services failed");
3005
3083
  } catch (error) {
3006
- console.log("error", error);
3084
+ console.log("AssemblyAI transcript also failed:", error);
3007
3085
  onTranscriptError({
3008
3086
  type: "TRANSCRIPT",
3009
- message: (error == null ? void 0 : error.message) || "Error getting transcript"
3087
+ message: (error == null ? void 0 : error.message) || "Error getting transcript from both services"
3010
3088
  });
3011
3089
  throw new Error(error);
3012
3090
  }
@@ -3061,7 +3139,8 @@ var useBaseOpenAI = ({
3061
3139
  // if the type = RESPOND_WRITE
3062
3140
  audio = null,
3063
3141
  autoGrade = true,
3064
- file = null
3142
+ file = null,
3143
+ pagePrompt = null
3065
3144
  }) => {
3066
3145
  try {
3067
3146
  if (!(feedbackAccess == null ? void 0 : feedbackAccess.canAccessFeedback)) {
@@ -3081,7 +3160,7 @@ var useBaseOpenAI = ({
3081
3160
  onTranscriptSuccess(writtenResponse);
3082
3161
  } else if (typeof audio === "string" && file) {
3083
3162
  if (feedbackAccess == null ? void 0 : feedbackAccess.canAccessFeedback) {
3084
- transcript = await getTranscript(audio, language);
3163
+ transcript = await getTranscript(audio, language, pagePrompt != null ? pagePrompt : "");
3085
3164
  audioUrl = audio;
3086
3165
  onTranscriptSuccess(transcript);
3087
3166
  } else {
@@ -3090,7 +3169,7 @@ var useBaseOpenAI = ({
3090
3169
  );
3091
3170
  }
3092
3171
  } else {
3093
- const response = await uploadAudioAndGetTranscript(audio || "", language);
3172
+ const response = await uploadAudioAndGetTranscript(audio || "", language, pagePrompt != null ? pagePrompt : "");
3094
3173
  transcript = response.transcript;
3095
3174
  audioUrl = response.audioUrl;
3096
3175
  }
@@ -3320,6 +3399,7 @@ export {
3320
3399
  useBaseOpenAI,
3321
3400
  useCards,
3322
3401
  useClearScore,
3402
+ useClearScoreV2,
3323
3403
  useCreateCard,
3324
3404
  useCreateCards,
3325
3405
  useCreateNotification,