Skip to content
GitLab
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in
Toggle navigation
Menu
Open sidebar
math_tutor_dev
public_math_tutor
Commits
f65e8af9
Commit
f65e8af9
authored
Jun 17, 2026
by
Kantz
Browse files
cleanup
parent
f1184f7f
Changes
11
Hide whitespace changes
Inline
Side-by-side
math-tutor/.gitignore
View file @
f65e8af9
...
@@ -6,6 +6,8 @@ venv/
...
@@ -6,6 +6,8 @@ venv/
.env-gwdg
.env-gwdg
.env-stochastik
.env-stochastik
__pycache__/
__pycache__/
*.pyc
drawings/
drawings/
backend/app/storage/
sources/
sources/
logs/
logs/
math-tutor/backend/requirements.txt
View file @
f65e8af9
...
@@ -13,7 +13,3 @@ pgvector
...
@@ -13,7 +13,3 @@ pgvector
pyyaml
pyyaml
sentence-transformers
sentence-transformers
transformers==4.57.6
torch
peft
torchvision
math-tutor/frontend/src/api/orchestratorApi.ts
View file @
f65e8af9
export
type
OrchestratorName
=
"
qa
"
|
"
tutor
"
|
"
task
"
|
"
socratic
"
;
import
{
DEFAULT_ORCHESTRATOR
,
FALLBACK_ORCHESTRATORS
,
normalizeOrchestrator
,
type
OrchestratorName
,
}
from
"
../utils/orchestrator
"
;
export
type
OrchestratorConfigResponse
=
{
export
type
OrchestratorConfigResponse
=
{
default_orchestrator
:
OrchestratorName
;
default_orchestrator
:
OrchestratorName
;
available_orchestrators
:
OrchestratorName
[];
available_orchestrators
:
OrchestratorName
[];
};
};
const
FALLBACK_ORCHESTRATORS
:
OrchestratorName
[]
=
[
"
qa
"
,
"
tutor
"
,
"
task
"
,
"
socratic
"
];
const
normalizeOrchestrator
=
(
value
:
string
):
OrchestratorName
|
null
=>
{
if
(
value
===
"
qa
"
||
value
===
"
tutor
"
||
value
===
"
task
"
||
value
===
"
socratic
"
)
{
return
value
;
}
return
null
;
};
export
const
getFallbackOrchestrators
=
():
OrchestratorName
[]
=>
export
const
getFallbackOrchestrators
=
():
OrchestratorName
[]
=>
[...
FALLBACK_ORCHESTRATORS
];
[...
FALLBACK_ORCHESTRATORS
];
...
@@ -30,7 +21,7 @@ export async function fetchOrchestratorConfig(): Promise<OrchestratorConfigRespo
...
@@ -30,7 +21,7 @@ export async function fetchOrchestratorConfig(): Promise<OrchestratorConfigRespo
const
payload
=
await
response
.
json
();
const
payload
=
await
response
.
json
();
const
defaultOrchestrator
=
const
defaultOrchestrator
=
normalizeOrchestrator
(
String
(
payload
?.
default_orchestrator
||
""
))
||
"
qa
"
;
normalizeOrchestrator
(
String
(
payload
?.
default_orchestrator
||
""
))
||
DEFAULT_ORCHESTRATOR
;
const
availableRaw
=
Array
.
isArray
(
payload
?.
available_orchestrators
)
const
availableRaw
=
Array
.
isArray
(
payload
?.
available_orchestrators
)
?
payload
.
available_orchestrators
?
payload
.
available_orchestrators
:
[];
:
[];
...
...
math-tutor/frontend/src/components/Orchestrator/OrchestratorSelect.tsx
View file @
f65e8af9
import
{
useId
}
from
"
react
"
;
import
{
useId
}
from
"
react
"
;
import
type
{
OrchestratorName
}
from
"
../../
api
/orchestrator
Api
"
;
import
type
{
OrchestratorName
}
from
"
../../
utils
/orchestrator
"
;
import
{
t
}
from
"
../../i18n
"
;
import
{
t
}
from
"
../../i18n
"
;
type
OrchestratorSelectProps
=
{
type
OrchestratorSelectProps
=
{
...
...
math-tutor/frontend/src/pages/App.tsx
View file @
f65e8af9
...
@@ -4,7 +4,7 @@ import ChatPage from "./ChatPage";
...
@@ -4,7 +4,7 @@ import ChatPage from "./ChatPage";
import
SocraticSelectionPage
from
"
./SocraticSelectionPage
"
;
import
SocraticSelectionPage
from
"
./SocraticSelectionPage
"
;
import
TaskSelectionPage
from
"
./TaskSelectionPage
"
;
import
TaskSelectionPage
from
"
./TaskSelectionPage
"
;
import
{
TutorSessionProvider
,
useTutorSession
}
from
"
../state/tutorSession
"
;
import
{
TutorSessionProvider
,
useTutorSession
}
from
"
../state/tutorSession
"
;
import
{
getSelectionRouteForOrchestrator
}
from
"
../utils/orchestrator
Routes
"
;
import
{
getSelectionRouteForOrchestrator
}
from
"
../utils/orchestrator
"
;
function
StartRoute
()
{
function
StartRoute
()
{
const
{
isTasksInitialized
,
selectedOrchestrator
}
=
useTutorSession
();
const
{
isTasksInitialized
,
selectedOrchestrator
}
=
useTutorSession
();
...
...
math-tutor/frontend/src/pages/ChatPage.tsx
View file @
f65e8af9
...
@@ -9,31 +9,20 @@ import SocraticPanel from "../components/Task/SocraticPanel";
...
@@ -9,31 +9,20 @@ import SocraticPanel from "../components/Task/SocraticPanel";
import
TaskPanel
from
"
../components/Task/TaskPanel
"
;
import
TaskPanel
from
"
../components/Task/TaskPanel
"
;
import
type
{
ChatMessage
}
from
"
../components/Chat/MessageList
"
;
import
type
{
ChatMessage
}
from
"
../components/Chat/MessageList
"
;
import
type
{
RetrievedDoc
}
from
"
../components/Retrieval/DocPanel
"
;
import
type
{
RetrievedDoc
}
from
"
../components/Retrieval/DocPanel
"
;
import
type
{
OrchestratorName
}
from
"
../api/orchestratorApi
"
;
import
{
selectTask
,
selectTopic
}
from
"
../api/taskApi
"
;
import
{
selectTask
,
selectTopic
}
from
"
../api/taskApi
"
;
import
{
t
}
from
"
../i18n
"
;
import
{
t
}
from
"
../i18n
"
;
import
{
createSessionId
,
useTutorSession
}
from
"
../state/tutorSession
"
;
import
{
createSessionId
,
useTutorSession
}
from
"
../state/tutorSession
"
;
import
{
getSelectionRouteForOrchestrator
,
isSocraticOrchestrator
}
from
"
../utils/orchestratorRoutes
"
;
import
{
getSelectionRouteForOrchestrator
,
isTaskCoupledOrchestrator
,
normalizeOrchestrator
,
type
OrchestratorName
,
}
from
"
../utils/orchestrator
"
;
import
{
normalizeTopicKey
as
normalizeTopicKey
}
from
"
../utils/topicKey
"
;
import
{
normalizeTopicKey
as
normalizeTopicKey
}
from
"
../utils/topicKey
"
;
import
sumintLogo
from
"
../../SuMINT-Logo.png
"
;
import
sumintLogo
from
"
../../SuMINT-Logo.png
"
;
const
initialMessages
:
ChatMessage
[]
=
[];
const
initialMessages
:
ChatMessage
[]
=
[];
const
normalizeOrchestrator
=
(
value
:
string
|
null
|
undefined
):
OrchestratorName
|
null
=>
{
if
(
value
===
"
qa
"
||
value
===
"
tutor
"
||
value
===
"
task
"
||
value
===
"
socratic
"
)
{
return
value
;
}
return
null
;
};
const
isTaskCoupledOrchestrator
=
(
value
:
string
|
null
|
undefined
):
boolean
=>
value
===
"
task
"
;
type
ArchivedChatSummary
=
{
type
ArchivedChatSummary
=
{
chat_id
:
string
;
chat_id
:
string
;
saved_at
:
string
;
saved_at
:
string
;
...
@@ -236,9 +225,10 @@ export default function ChatPage() {
...
@@ -236,9 +225,10 @@ export default function ChatPage() {
const
socraticBootstrapRef
=
useRef
<
string
>
(
""
);
const
socraticBootstrapRef
=
useRef
<
string
>
(
""
);
const
deepLinkTarget
=
useMemo
(()
=>
{
const
deepLinkTarget
=
useMemo
(()
=>
{
const
orchestrator
=
String
(
searchParams
.
get
(
"
orchestrator
"
)
||
""
)
const
orchestrator
Value
=
String
(
searchParams
.
get
(
"
orchestrator
"
)
||
""
)
.
trim
()
.
trim
()
.
toLowerCase
();
.
toLowerCase
();
const
orchestrator
=
normalizeOrchestrator
(
orchestratorValue
);
const
fileId
=
String
(
searchParams
.
get
(
"
file_id
"
)
||
""
).
trim
();
const
fileId
=
String
(
searchParams
.
get
(
"
file_id
"
)
||
""
).
trim
();
const
rawTaskId
=
String
(
searchParams
.
get
(
"
task_id
"
)
||
""
).
trim
();
const
rawTaskId
=
String
(
searchParams
.
get
(
"
task_id
"
)
||
""
).
trim
();
const
rawTopicKey
=
String
(
const
rawTopicKey
=
String
(
...
@@ -252,12 +242,12 @@ export default function ChatPage() {
...
@@ -252,12 +242,12 @@ export default function ChatPage() {
const
hasFileId
=
Boolean
(
fileId
);
const
hasFileId
=
Boolean
(
fileId
);
const
hasTaskId
=
Boolean
(
taskId
);
const
hasTaskId
=
Boolean
(
taskId
);
const
hasTopicKey
=
Boolean
(
topicKey
);
const
hasTopicKey
=
Boolean
(
topicKey
);
const
isTaskOrchestrator
=
isTaskCoupledOrchestrator
(
orchestrator
)
;
const
isTaskOrchestrator
=
orchestrator
===
"
task
"
;
const
isSocratic
=
isSocraticOrchestrator
(
orchestrator
as
OrchestratorName
)
;
const
isSocratic
=
orchestrator
===
"
socratic
"
;
const
hasAnyTaskParam
=
hasFileId
||
hasTaskId
||
hasTopicKey
;
const
hasAnyTaskParam
=
hasFileId
||
hasTaskId
||
hasTopicKey
;
const
hasRequiredTaskParams
=
hasFileId
&&
hasTaskId
;
const
hasRequiredTaskParams
=
hasFileId
&&
hasTaskId
;
const
hasRequiredTopicParams
=
hasTopicKey
;
const
hasRequiredTopicParams
=
hasTopicKey
;
const
key
=
`
${
orchestrator
}
|
${
fileId
}
|
${
taskId
}
|
${
topicKey
}
`
;
const
key
=
`
${
orchestrator
Value
}
|
${
fileId
}
|
${
taskId
}
|
${
topicKey
}
`
;
return
{
return
{
fileId
,
fileId
,
...
...
math-tutor/frontend/src/pages/SocraticSelectionPage.tsx
View file @
f65e8af9
import
{
useEffect
,
useMemo
,
useRef
}
from
"
react
"
;
import
{
useEffect
,
useMemo
,
useRef
}
from
"
react
"
;
import
{
useNavigate
}
from
"
react-router-dom
"
;
import
{
useNavigate
}
from
"
react-router-dom
"
;
import
type
{
OrchestratorName
}
from
"
../api/orchestratorApi
"
;
import
{
selectTopic
}
from
"
../api/taskApi
"
;
import
{
selectTopic
}
from
"
../api/taskApi
"
;
import
OrchestratorSelect
from
"
../components/Orchestrator/OrchestratorSelect
"
;
import
OrchestratorSelect
from
"
../components/Orchestrator/OrchestratorSelect
"
;
import
{
t
}
from
"
../i18n
"
;
import
{
t
}
from
"
../i18n
"
;
import
{
useTutorSession
}
from
"
../state/tutorSession
"
;
import
{
useTutorSession
}
from
"
../state/tutorSession
"
;
import
{
getSelectionRouteForOrchestrator
}
from
"
../utils/orchestratorRoutes
"
;
import
{
getSelectionRouteForOrchestrator
,
type
OrchestratorName
,
}
from
"
../utils/orchestrator
"
;
import
"
../styles/theme.css
"
;
import
"
../styles/theme.css
"
;
import
sumintLogo
from
"
../../SuMINT-Logo.png
"
;
import
sumintLogo
from
"
../../SuMINT-Logo.png
"
;
...
...
math-tutor/frontend/src/pages/TaskSelectionPage.tsx
View file @
f65e8af9
import
{
useEffect
,
useRef
}
from
"
react
"
;
import
{
useEffect
,
useRef
}
from
"
react
"
;
import
{
useNavigate
}
from
"
react-router-dom
"
;
import
{
useNavigate
}
from
"
react-router-dom
"
;
import
type
{
OrchestratorName
}
from
"
../api/orchestratorApi
"
;
import
OrchestratorSelect
from
"
../components/Orchestrator/OrchestratorSelect
"
;
import
OrchestratorSelect
from
"
../components/Orchestrator/OrchestratorSelect
"
;
import
TaskContent
from
"
../components/Task/TaskContent
"
;
import
TaskContent
from
"
../components/Task/TaskContent
"
;
import
{
selectTask
}
from
"
../api/taskApi
"
;
import
{
selectTask
}
from
"
../api/taskApi
"
;
import
{
t
}
from
"
../i18n
"
;
import
{
t
}
from
"
../i18n
"
;
import
{
useTutorSession
}
from
"
../state/tutorSession
"
;
import
{
useTutorSession
}
from
"
../state/tutorSession
"
;
import
{
getSelectionRouteForOrchestrator
}
from
"
../utils/orchestratorRoutes
"
;
import
{
getSelectionRouteForOrchestrator
,
type
OrchestratorName
,
}
from
"
../utils/orchestrator
"
;
import
"
../styles/theme.css
"
;
import
"
../styles/theme.css
"
;
import
sumintLogo
from
"
../../SuMINT-Logo.png
"
;
import
sumintLogo
from
"
../../SuMINT-Logo.png
"
;
...
...
math-tutor/frontend/src/state/tutorSession.tsx
View file @
f65e8af9
...
@@ -13,8 +13,12 @@ import { t } from "../i18n";
...
@@ -13,8 +13,12 @@ import { t } from "../i18n";
import
{
import
{
fetchOrchestratorConfig
,
fetchOrchestratorConfig
,
getFallbackOrchestrators
,
getFallbackOrchestrators
,
type
OrchestratorName
,
}
from
"
../api/orchestratorApi
"
;
}
from
"
../api/orchestratorApi
"
;
import
{
DEFAULT_ORCHESTRATOR
,
isTaskCoupledOrchestrator
,
type
OrchestratorName
,
}
from
"
../utils/orchestrator
"
;
import
{
import
{
fetchTaskDetails
,
fetchTaskDetails
,
fetchSocraticTopics
,
fetchSocraticTopics
,
...
@@ -93,16 +97,13 @@ export const getDefaultTaskId = (tasks: Array<{ task_id: string }>): string =>
...
@@ -93,16 +97,13 @@ export const getDefaultTaskId = (tasks: Array<{ task_id: string }>): string =>
const
isSelectableTaskFile
=
(
file
:
TaskFile
):
boolean
=>
const
isSelectableTaskFile
=
(
file
:
TaskFile
):
boolean
=>
Array
.
isArray
(
file
.
tasks
)
&&
file
.
tasks
.
length
>
0
;
Array
.
isArray
(
file
.
tasks
)
&&
file
.
tasks
.
length
>
0
;
const
isTaskCoupledOrchestrator
=
(
value
:
OrchestratorName
):
boolean
=>
value
===
"
task
"
||
value
===
"
socratic
"
;
const
formatTopicRefs
=
(
refs
:
[
number
,
number
,
number
,
number
][]):
string
=>
const
formatTopicRefs
=
(
refs
:
[
number
,
number
,
number
,
number
][]):
string
=>
refs
.
map
((
ref
)
=>
ref
.
join
(
"
:
"
)).
join
(
"
,
"
);
refs
.
map
((
ref
)
=>
ref
.
join
(
"
:
"
)).
join
(
"
,
"
);
export
function
TutorSessionProvider
({
children
}:
PropsWithChildren
)
{
export
function
TutorSessionProvider
({
children
}:
PropsWithChildren
)
{
const
[
chatSessionId
,
setChatSessionId
]
=
useState
<
string
>
(()
=>
createSessionId
());
const
[
chatSessionId
,
setChatSessionId
]
=
useState
<
string
>
(()
=>
createSessionId
());
const
[
selectedOrchestrator
,
setSelectedOrchestratorState
]
=
const
[
selectedOrchestrator
,
setSelectedOrchestratorState
]
=
useState
<
OrchestratorName
>
(
"
qa
"
);
useState
<
OrchestratorName
>
(
DEFAULT_ORCHESTRATOR
);
const
[
availableOrchestrators
,
setAvailableOrchestrators
]
=
useState
<
OrchestratorName
[]
>
(
const
[
availableOrchestrators
,
setAvailableOrchestrators
]
=
useState
<
OrchestratorName
[]
>
(
()
=>
getFallbackOrchestrators
()
()
=>
getFallbackOrchestrators
()
);
);
...
...
math-tutor/frontend/src/utils/orchestrator.ts
0 → 100644
View file @
f65e8af9
export
const
ORCHESTRATORS
=
[
"
qa
"
,
"
tutor
"
,
"
task
"
,
"
socratic
"
]
as
const
;
export
type
OrchestratorName
=
(
typeof
ORCHESTRATORS
)[
number
];
export
const
DEFAULT_ORCHESTRATOR
:
OrchestratorName
=
"
qa
"
;
export
const
FALLBACK_ORCHESTRATORS
:
OrchestratorName
[]
=
[...
ORCHESTRATORS
];
export
const
normalizeOrchestrator
=
(
value
:
string
|
null
|
undefined
):
OrchestratorName
|
null
=>
{
if
(
typeof
value
!==
"
string
"
)
{
return
null
;
}
return
ORCHESTRATORS
.
find
((
item
)
=>
item
===
value
)
??
null
;
};
export
const
isSocraticOrchestrator
=
(
value
:
OrchestratorName
):
boolean
=>
value
===
"
socratic
"
;
export
const
isTaskSelectionOrchestrator
=
(
value
:
OrchestratorName
):
boolean
=>
value
===
"
task
"
;
export
const
isTaskCoupledOrchestrator
=
(
value
:
OrchestratorName
):
boolean
=>
value
===
"
task
"
||
value
===
"
socratic
"
;
export
const
getSelectionRouteForOrchestrator
=
(
value
:
OrchestratorName
):
string
=>
{
if
(
value
===
"
socratic
"
)
{
return
"
/select-socratic
"
;
}
if
(
value
===
"
task
"
)
{
return
"
/select-task
"
;
}
return
"
/chat
"
;
};
math-tutor/frontend/src/utils/orchestratorRoutes.ts
View file @
f65e8af9
import
type
{
OrchestratorName
}
from
"
../api/orchestratorApi
"
;
export
{
getSelectionRouteForOrchestrator
,
export
const
isTaskSelectionOrchestrator
=
(
value
:
OrchestratorName
):
boolean
=>
isSocraticOrchestrator
,
value
===
"
task
"
;
isTaskSelectionOrchestrator
,
type
OrchestratorName
,
export
const
isSocraticOrchestrator
=
(
value
:
OrchestratorName
):
boolean
=>
}
from
"
./orchestrator
"
;
value
===
"
socratic
"
;
export
const
getSelectionRouteForOrchestrator
=
(
value
:
OrchestratorName
):
string
=>
{
if
(
value
===
"
socratic
"
)
{
return
"
/select-socratic
"
;
}
if
(
value
===
"
task
"
)
{
return
"
/select-task
"
;
}
return
"
/chat
"
;
};
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment