hydro-ai-helper 2.2.0 → 2.4.0

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.
Files changed (85) hide show
  1. package/README.md +10 -0
  2. package/dist/constants/updateChannel.js +44 -0
  3. package/dist/constants/updateChannel.js.map +1 -0
  4. package/dist/handlers/adminConfigHandler.js +30 -0
  5. package/dist/handlers/adminConfigHandler.js.map +1 -1
  6. package/dist/handlers/batchSummaryHandler.js +15 -8
  7. package/dist/handlers/batchSummaryHandler.js.map +1 -1
  8. package/dist/handlers/studentHandler.js +1 -1
  9. package/dist/handlers/studentHandler.js.map +1 -1
  10. package/dist/handlers/teachingSummaryHandler.js +38 -9
  11. package/dist/handlers/teachingSummaryHandler.js.map +1 -1
  12. package/dist/handlers/versionHandler.js +2 -1
  13. package/dist/handlers/versionHandler.js.map +1 -1
  14. package/dist/index.js +3 -1
  15. package/dist/index.js.map +1 -1
  16. package/dist/models/aiConfig.js +15 -2
  17. package/dist/models/aiConfig.js.map +1 -1
  18. package/dist/models/studentSummary.js +13 -0
  19. package/dist/models/studentSummary.js.map +1 -1
  20. package/dist/models/teachingSummary.js +2 -0
  21. package/dist/models/teachingSummary.js.map +1 -1
  22. package/dist/services/analyzers/errorClusterAnalyzer.js +1 -0
  23. package/dist/services/analyzers/errorClusterAnalyzer.js.map +1 -1
  24. package/dist/services/analyzers/findingConsolidator.js +172 -0
  25. package/dist/services/analyzers/findingConsolidator.js.map +1 -0
  26. package/dist/services/batchSummaryService.js +85 -51
  27. package/dist/services/batchSummaryService.js.map +1 -1
  28. package/dist/services/openaiClient.js +59 -28
  29. package/dist/services/openaiClient.js.map +1 -1
  30. package/dist/services/promptService.js +49 -24
  31. package/dist/services/promptService.js.map +1 -1
  32. package/dist/services/teachingAnalysisService.js +13 -2
  33. package/dist/services/teachingAnalysisService.js.map +1 -1
  34. package/dist/services/teachingSuggestionService.js +43 -44
  35. package/dist/services/teachingSuggestionService.js.map +1 -1
  36. package/dist/services/telemetryService.js +8 -1
  37. package/dist/services/telemetryService.js.map +1 -1
  38. package/dist/services/updateService.js +106 -11
  39. package/dist/services/updateService.js.map +1 -1
  40. package/dist/services/versionService.js +88 -61
  41. package/dist/services/versionService.js.map +1 -1
  42. package/dist/utils/semver.js +75 -0
  43. package/dist/utils/semver.js.map +1 -0
  44. package/frontend/admin/BudgetConfigForm.tsx +1 -1
  45. package/frontend/admin/ConfigPanel.tsx +53 -3
  46. package/frontend/admin/EndpointManager.tsx +1 -1
  47. package/frontend/admin/FeedbackForm.tsx +1 -1
  48. package/frontend/admin/JailbreakLogsViewer.tsx +1 -1
  49. package/frontend/admin/ScenarioModelSelector.tsx +238 -0
  50. package/frontend/admin/TelemetrySettings.tsx +1 -1
  51. package/frontend/admin/VersionBadge.tsx +26 -1
  52. package/frontend/admin/configTypes.ts +9 -0
  53. package/frontend/batchSummary/BatchSummaryPanel.tsx +29 -1
  54. package/frontend/batchSummary/StudentSummaryView.tsx +47 -14
  55. package/frontend/batchSummary/SummaryCard.tsx +1 -1
  56. package/frontend/batchSummary/useBatchSummary.ts +26 -8
  57. package/frontend/components/AIHelperDashboard.tsx +1 -1
  58. package/frontend/components/ErrorBoundary.tsx +1 -1
  59. package/frontend/components/ScoreboardTabContainer.tsx +1 -1
  60. package/frontend/generated/localeFallback.ts +1502 -0
  61. package/frontend/problem_detail.page.tsx +1 -1
  62. package/frontend/student/AIAssistantPanel.tsx +1 -1
  63. package/frontend/student/ChatInput.tsx +1 -1
  64. package/frontend/student/ChatMessageList.tsx +1 -1
  65. package/frontend/student/ThinkingBlock.tsx +1 -1
  66. package/frontend/student/hooks/useChatSession.ts +1 -1
  67. package/frontend/teacher/AnalyticsPage.tsx +1 -1
  68. package/frontend/teacher/ClassAnalyticsTable.tsx +1 -1
  69. package/frontend/teacher/ConversationDetail.tsx +1 -1
  70. package/frontend/teacher/ConversationDetailModal.tsx +1 -1
  71. package/frontend/teacher/ConversationList.tsx +1 -1
  72. package/frontend/teacher/CostDashboard.tsx +1 -1
  73. package/frontend/teacher/ExportDialog.tsx +1 -1
  74. package/frontend/teacher/MetricsPanel.tsx +1 -1
  75. package/frontend/teacher/ProblemAnalyticsTable.tsx +1 -1
  76. package/frontend/teacher/StudentAnalyticsTable.tsx +1 -1
  77. package/frontend/teacher/analyticsTypes.ts +1 -1
  78. package/frontend/teachingSummary/TeachingReviewPanel.tsx +1 -1
  79. package/frontend/teachingSummary/TeachingSummaryPanel.tsx +525 -175
  80. package/frontend/teachingSummary/useTeachingSummary.ts +10 -0
  81. package/frontend/utils/i18n.ts +32 -0
  82. package/frontend/utils/i18nFallbackCore.ts +30 -0
  83. package/locales/en.yaml +43 -6
  84. package/locales/zh.yaml +43 -6
  85. package/package.json +3 -1
@@ -5,7 +5,7 @@
5
5
  */
6
6
 
7
7
  import React, { useState } from 'react';
8
- import { i18n } from '@hydrooj/ui-default';
8
+ import { i18n } from '../utils/i18n';
9
9
  import {
10
10
  COLORS, SPACING, RADIUS, SHADOWS, getButtonStyle,
11
11
  } from '../utils/styles';
@@ -9,6 +9,13 @@ export interface StudentSummaryData {
9
9
  error?: string;
10
10
  }
11
11
 
12
+ /** Outcome of a publish-all call — lets the panel warn about skipped students */
13
+ export interface PublishResult {
14
+ published: number;
15
+ skippedFailed: number;
16
+ skippedPending: number;
17
+ }
18
+
12
19
  export interface BatchSummaryState {
13
20
  jobId: string | null;
14
21
  jobStatus: string | null;
@@ -20,6 +27,7 @@ export interface BatchSummaryState {
20
27
  summaries: Map<number, StudentSummaryData>;
21
28
  error: string | null;
22
29
  loading: boolean;
30
+ publishResult: PublishResult | null;
23
31
  }
24
32
 
25
33
  const initialState: BatchSummaryState = {
@@ -33,6 +41,7 @@ const initialState: BatchSummaryState = {
33
41
  summaries: new Map(),
34
42
  error: null,
35
43
  loading: false,
44
+ publishResult: null,
36
45
  };
37
46
 
38
47
  /** Extract a string message from backend error responses ({ error: string | { code, message } }) */
@@ -244,6 +253,7 @@ export function useBatchSummary(domainId: string) {
244
253
  summaries,
245
254
  error: null,
246
255
  loading: false,
256
+ publishResult: null,
247
257
  });
248
258
  } catch (err) {
249
259
  setState(prev => ({ ...prev, loading: false }));
@@ -261,9 +271,9 @@ export function useBatchSummary(domainId: string) {
261
271
 
262
272
  // For new_only mode, don't clear existing summaries
263
273
  if (mode !== 'new_only') {
264
- setState(prev => ({ ...prev, isGenerating: true, error: null, summaries: new Map(), completed: 0, failed: 0 }));
274
+ setState(prev => ({ ...prev, isGenerating: true, error: null, publishResult: null, summaries: new Map(), completed: 0, failed: 0 }));
265
275
  } else {
266
- setState(prev => ({ ...prev, isGenerating: true, error: null }));
276
+ setState(prev => ({ ...prev, isGenerating: true, error: null, publishResult: null }));
267
277
  }
268
278
 
269
279
  try {
@@ -348,7 +358,7 @@ export function useBatchSummary(domainId: string) {
348
358
  const continueGeneration = useCallback(async () => {
349
359
  if (!state.jobId) return;
350
360
 
351
- setState(prev => ({ ...prev, isGenerating: true, error: null }));
361
+ setState(prev => ({ ...prev, isGenerating: true, error: null, publishResult: null }));
352
362
 
353
363
  try {
354
364
  const res = await fetch(buildUrl(domainId, `/${state.jobId}/continue`), {
@@ -385,7 +395,7 @@ export function useBatchSummary(domainId: string) {
385
395
  }, [domainId, state.jobId, readSSEStream]);
386
396
 
387
397
  const loadExisting = useCallback(async (jobId: string) => {
388
- setState(prev => ({ ...prev, error: null }));
398
+ setState(prev => ({ ...prev, error: null, publishResult: null }));
389
399
  try {
390
400
  const res = await fetch(buildUrl(domainId, `/jobs/${jobId}`), {
391
401
  credentials: 'include',
@@ -427,7 +437,7 @@ export function useBatchSummary(domainId: string) {
427
437
 
428
438
  const publishAll = useCallback(async () => {
429
439
  if (!state.jobId) return;
430
- setState(prev => ({ ...prev, error: null }));
440
+ setState(prev => ({ ...prev, error: null, publishResult: null }));
431
441
  try {
432
442
  const res = await fetch(buildUrl(domainId, `/${state.jobId}/publish`), {
433
443
  method: 'POST',
@@ -443,6 +453,14 @@ export function useBatchSummary(domainId: string) {
443
453
  setState(prev => ({ ...prev, error: extractErrorMsg(errData, `HTTP ${res.status}`) }));
444
454
  return;
445
455
  }
456
+ // Backend reports how many students publishAll skipped (failed/pending) —
457
+ // surface that instead of implying every student was published.
458
+ const data = await res.json().catch(() => ({} as any));
459
+ const publishResult: PublishResult = {
460
+ published: Number(data.published ?? 0),
461
+ skippedFailed: Number(data.skippedFailed ?? 0),
462
+ skippedPending: Number(data.skippedPending ?? 0),
463
+ };
446
464
  // Update all completed summaries to published
447
465
  setState(prev => {
448
466
  const next = new Map(prev.summaries);
@@ -451,7 +469,7 @@ export function useBatchSummary(domainId: string) {
451
469
  next.set(uid, { ...s, publishStatus: 'published' });
452
470
  }
453
471
  }
454
- return { ...prev, summaries: next };
472
+ return { ...prev, summaries: next, publishResult };
455
473
  });
456
474
  } catch (err) {
457
475
  const errMsg = err instanceof Error ? err.message : 'Unknown error';
@@ -461,7 +479,7 @@ export function useBatchSummary(domainId: string) {
461
479
 
462
480
  const retryStudent = useCallback(async (userId: number) => {
463
481
  if (!state.jobId) return;
464
- setState(prev => ({ ...prev, error: null }));
482
+ setState(prev => ({ ...prev, error: null, publishResult: null }));
465
483
  // Optimistically set student to pending
466
484
  updateSummary(userId, { status: 'pending', error: undefined });
467
485
  try {
@@ -490,7 +508,7 @@ export function useBatchSummary(domainId: string) {
490
508
  /** Reset all failed students to pending, then trigger continue generation */
491
509
  const retryFailed = useCallback(async () => {
492
510
  if (!state.jobId) return;
493
- setState(prev => ({ ...prev, error: null }));
511
+ setState(prev => ({ ...prev, error: null, publishResult: null }));
494
512
 
495
513
  try {
496
514
  // 1. Batch-reset all failed → pending
@@ -4,7 +4,7 @@
4
4
  */
5
5
 
6
6
  import React, { useState, useEffect } from 'react';
7
- import { i18n } from '@hydrooj/ui-default';
7
+ import { i18n } from '../utils/i18n';
8
8
  import { AnalyticsPage } from '../teacher/AnalyticsPage';
9
9
  import { ConversationList } from '../teacher/ConversationList';
10
10
  import { ConfigPanel } from '../admin/ConfigPanel';
@@ -1,5 +1,5 @@
1
1
  import React from 'react';
2
- import { i18n } from '@hydrooj/ui-default';
2
+ import { i18n } from '../utils/i18n';
3
3
  import { COLORS } from '../utils/styles';
4
4
 
5
5
  interface ErrorBoundaryProps {
@@ -11,7 +11,7 @@
11
11
  */
12
12
 
13
13
  import React, { useState, useEffect, useCallback, useMemo, useRef } from 'react';
14
- import { i18n } from '@hydrooj/ui-default';
14
+ import { i18n } from '../utils/i18n';
15
15
  import { COLORS, SPACING, RADIUS, SHADOWS } from '../utils/styles';
16
16
  import { TeachingSummaryPanel } from '../teachingSummary/TeachingSummaryPanel';
17
17
  import { BatchSummaryPanel } from '../batchSummary/BatchSummaryPanel';