Commit bf7cc21d authored by Kantz's avatar Kantz
Browse files

orchestator API removed caus not longer relevant

parent cd7358c0
......@@ -11,7 +11,6 @@ LLM_TOOL_USE_ENABLED="False" # "True" or "False"
MCP_SHARED_SECRET=""
MCP_BASE_URL=""
ORCHESTRATOR="task" # "tutor", "task" or "qa"
TASK_FOLDER="tasks"
LLM_PROVIDER="gwdg" # "openai", "gwdg", "mistral", or "ollama"
......
from __future__ import annotations
from fastapi import APIRouter
from pydantic import BaseModel
from app.deterministic_services.orchestrators.registry import (
AVAILABLE_ORCHESTRATORS,
get_default_orchestrator,
)
router = APIRouter()
class OrchestratorConfigResponse(BaseModel):
default_orchestrator: str
available_orchestrators: list[str]
@router.get("/api/orchestrator/config", response_model=OrchestratorConfigResponse)
def get_orchestrator_config() -> OrchestratorConfigResponse:
return OrchestratorConfigResponse(
default_orchestrator=get_default_orchestrator(),
available_orchestrators=list(AVAILABLE_ORCHESTRATORS),
)
......@@ -6,13 +6,10 @@ from fastapi import APIRouter, HTTPException
from fastapi.responses import FileResponse
from pydantic import BaseModel, Field
import app.config as config
from app.deterministic_services import context_store, task_catalog, socratic_oranisator
router = APIRouter()
TASK_ORCHESTRATORS = {"task", "socratic"}
class TaskImage(BaseModel):
src: str
......@@ -38,8 +35,6 @@ class TaskFile(BaseModel):
class TasksResponse(BaseModel):
orchestrator: str
enabled: bool
task_files: List[TaskFile]
......@@ -52,8 +47,6 @@ class TaskDetailsResponse(BaseModel):
class SocraticResponse(BaseModel):
orchestrator: str
enabled: bool
topics: List[TopicEntry] = Field(default_factory=list)
class SelectTaskRequest(BaseModel):
......@@ -108,11 +101,8 @@ def get_task_asset(asset_path: str) -> FileResponse:
@router.get("/api/tasks", response_model=TasksResponse)
def list_tasks() -> TasksResponse:
orchestrator = config.get_orchestrator()
task_files = list(task_catalog.build_cached_task_metadata_catalog())
return TasksResponse(
orchestrator=orchestrator,
enabled=orchestrator in TASK_ORCHESTRATORS,
task_files=task_files,
)
......@@ -127,11 +117,8 @@ def get_task_details(file_id: str, task_id: str) -> TaskDetailsResponse:
@router.get("/api/tasks/socratic-topics", response_model=SocraticResponse)
def list_socratic_topics() -> SocraticResponse:
orchestrator = config.get_orchestrator()
topics = socratic_oranisator.build_topic_catalog()
return SocraticResponse(
orchestrator=orchestrator,
enabled=orchestrator == "socratic",
topics=topics,
)
......
......@@ -23,11 +23,6 @@ class EmbeddingSettings(BaseModel):
target_dim: int = 1024
def get_orchestrator() -> str:
return os.getenv("ORCHESTRATOR", "qa").lower()
def get_task_folder() -> Path:
value = os.getenv("TASK_FOLDER", "tasks").strip()
if not value:
......
......@@ -2,7 +2,6 @@ from __future__ import annotations
from typing import Any
import app.config as config
from app.deterministic_services.orchestrators import (
orchestrator_qa,
orchestrator_socratic,
......@@ -11,6 +10,7 @@ from app.deterministic_services.orchestrators import (
)
AVAILABLE_ORCHESTRATORS: tuple[str, ...] = ("qa", "tutor", "task", "socratic")
DEFAULT_ORCHESTRATOR = "qa"
_ORCHESTRATOR_MODULES: dict[str, Any] = {
"qa": orchestrator_qa,
......@@ -21,10 +21,7 @@ _ORCHESTRATOR_MODULES: dict[str, Any] = {
def get_default_orchestrator() -> str:
configured = str(config.get_orchestrator() or "").strip().lower()
if configured in _ORCHESTRATOR_MODULES:
return configured
return "qa"
return DEFAULT_ORCHESTRATOR
def is_valid_orchestrator(value: str) -> bool:
......
......@@ -3,7 +3,7 @@ import logging
from fastapi import FastAPI
from fastapi.middleware.cors import CORSMiddleware
from app.api import canvas, chat, context, health, orchestrator, tasks
from app.api import canvas, chat, context, health, tasks
from app.config import get_frontend_url
from app.deterministic_services import embedding_provider, llm_quota
from app import config
......@@ -58,5 +58,4 @@ app.include_router(chat.router)
app.include_router(canvas.router)
app.include_router(context.router)
app.include_router(health.router)
app.include_router(orchestrator.router)
app.include_router(tasks.router)
......@@ -431,7 +431,7 @@ class TaskApiSocraticTest(unittest.TestCase):
}
]
with patch("app.api.tasks.config.get_orchestrator", return_value="socratic"), patch(
with patch(
"app.api.tasks.task_catalog.build_cached_task_metadata_catalog",
return_value=payload,
):
......@@ -439,7 +439,6 @@ class TaskApiSocraticTest(unittest.TestCase):
self.assertEqual(response.status_code, 200)
body = response.json()
self.assertEqual(body["orchestrator"], "socratic")
self.assertEqual(body["task_files"], payload)
self.assertNotIn("topics", body)
......@@ -505,7 +504,7 @@ class TaskApiSocraticTest(unittest.TestCase):
}
]
with patch("app.api.tasks.config.get_orchestrator", return_value="socratic"), patch(
with patch(
"app.api.tasks.socratic_oranisator.build_topic_catalog",
return_value=topics,
):
......@@ -513,8 +512,6 @@ class TaskApiSocraticTest(unittest.TestCase):
self.assertEqual(response.status_code, 200)
body = response.json()
self.assertEqual(body["orchestrator"], "socratic")
self.assertTrue(body["enabled"])
self.assertEqual(body["topics"], topics)
def test_select_topic_endpoint_returns_selected_key(self) -> None:
......
import {
DEFAULT_ORCHESTRATOR,
FALLBACK_ORCHESTRATORS,
normalizeOrchestrator,
type OrchestratorName,
} from "../utils/orchestrator";
export type OrchestratorConfigResponse = {
default_orchestrator: OrchestratorName;
available_orchestrators: OrchestratorName[];
};
export const getFallbackOrchestrators = (): OrchestratorName[] =>
[...FALLBACK_ORCHESTRATORS];
export async function fetchOrchestratorConfig(): Promise<OrchestratorConfigResponse> {
const response = await fetch("/api/orchestrator/config");
if (!response.ok) {
throw new Error(`Orchestrator config failed: ${response.status}`);
}
const payload = await response.json();
const defaultOrchestrator =
normalizeOrchestrator(String(payload?.default_orchestrator || "")) || DEFAULT_ORCHESTRATOR;
const availableRaw = Array.isArray(payload?.available_orchestrators)
? payload.available_orchestrators
: [];
const available = availableRaw
.map((item: unknown) => normalizeOrchestrator(String(item || "")))
.filter((item: OrchestratorName | null): item is OrchestratorName => Boolean(item));
return {
default_orchestrator: defaultOrchestrator,
available_orchestrators: available.length ? available : getFallbackOrchestrators(),
};
}
......@@ -21,8 +21,6 @@ export type TopicOption = {
};
export type TasksResponse = {
orchestrator: string;
enabled: boolean;
task_files: TaskFile[];
};
......@@ -35,8 +33,6 @@ export type TaskDetailsResponse = {
};
export type SocraticResponse = {
orchestrator: string;
enabled: boolean;
topics: TopicOption[];
};
......
......@@ -56,7 +56,6 @@
noSavedChatsYet: "No saved chats yet.",
canvasHidden: "Canvas hidden",
failedLoadTasks: "Could not load tasks.",
failedLoadOrchestratorConfig: "Could not load orchestrator config. Fallback mode active.",
chatRequestFailed: "The chat request failed. Please check backend logs.",
noStoredSolution: "No stored solution is available for this task yet.",
retrievalFailed: "Source retrieval failed. Please check backend logs.",
......@@ -156,8 +155,6 @@
noSavedChatsYet: "Noch keine gespeicherten Chats.",
canvasHidden: "Canvas ausgeblendet",
failedLoadTasks: "Aufgaben konnten nicht geladen werden.",
failedLoadOrchestratorConfig:
"Orchestrator-Konfiguration konnte nicht geladen werden. Fallback-Modus aktiv.",
chatRequestFailed:
"Da ist wohl die Chat-Anfrage fehlgeschlagen. Gib gerne deinem Dozenten bescheid. In vielen Fällen hilft es die Seite neu zu laden.",
noStoredSolution:
......
......@@ -10,12 +10,9 @@ import {
type PropsWithChildren,
} from "react";
import { t } from "../i18n";
import {
fetchOrchestratorConfig,
getFallbackOrchestrators,
} from "../api/orchestratorApi";
import {
DEFAULT_ORCHESTRATOR,
FALLBACK_ORCHESTRATORS,
isTaskCoupledOrchestrator,
type OrchestratorName,
} from "../utils/orchestrator";
......@@ -105,10 +102,8 @@ export function TutorSessionProvider({ children }: PropsWithChildren) {
const [selectedOrchestrator, setSelectedOrchestratorState] =
useState<OrchestratorName>(DEFAULT_ORCHESTRATOR);
const [availableOrchestrators, setAvailableOrchestrators] = useState<OrchestratorName[]>(
() => getFallbackOrchestrators()
() => [...FALLBACK_ORCHESTRATORS]
);
const [isOrchestratorSelectable, setIsOrchestratorSelectable] = useState(false);
const [orchestratorError, setOrchestratorError] = useState<string | null>(null);
const [isTasksInitialized, setIsTasksInitialized] = useState(false);
const [taskFiles, setTaskFiles] = useState<TaskFile[]>([]);
const [topics, setTopics] = useState<TopicOption[]>([]);
......@@ -317,26 +312,19 @@ export function TutorSessionProvider({ children }: PropsWithChildren) {
}, [loadTaskDetails]);
const initTasks = useCallback(async () => {
setOrchestratorError(null);
try {
const orchestratorPayload = await fetchOrchestratorConfig();
const available = orchestratorPayload.available_orchestrators.length
? orchestratorPayload.available_orchestrators
: getFallbackOrchestrators();
const available = [...FALLBACK_ORCHESTRATORS];
const nextOrchestrator = available.includes(selectedOrchestrator)
? selectedOrchestrator
: orchestratorPayload.default_orchestrator;
: DEFAULT_ORCHESTRATOR;
setAvailableOrchestrators(available);
setIsOrchestratorSelectable(true);
setSelectedOrchestratorState(nextOrchestrator);
await loadSelectionData(nextOrchestrator);
} catch (error) {
setAvailableOrchestrators(getFallbackOrchestrators());
setSelectedOrchestratorState("qa");
setIsOrchestratorSelectable(false);
setOrchestratorError(t("failedLoadOrchestratorConfig"));
await loadSelectionData("qa");
setAvailableOrchestrators([...FALLBACK_ORCHESTRATORS]);
setSelectedOrchestratorState(DEFAULT_ORCHESTRATOR);
await loadSelectionData(DEFAULT_ORCHESTRATOR);
void error;
} finally {
setIsTasksInitialized(true);
......@@ -477,8 +465,8 @@ export function TutorSessionProvider({ children }: PropsWithChildren) {
availableOrchestrators,
setSelectedOrchestrator,
switchOrchestrator,
isOrchestratorSelectable,
orchestratorError,
isOrchestratorSelectable: true,
orchestratorError: null,
taskFiles,
topics,
selectedTaskRef,
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment