Skip to content

Commit

Permalink
Merge branch 'feat/course-chat/agent'
Browse files Browse the repository at this point in the history
  • Loading branch information
bassner committed Jun 21, 2024
2 parents e02165f + 855c4a2 commit d28a3c7
Show file tree
Hide file tree
Showing 61 changed files with 1,187 additions and 636 deletions.
22 changes: 10 additions & 12 deletions app/common/message_converters.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
from datetime import datetime
from typing import Literal

from langchain_core.messages import BaseMessage
from langchain_core.messages import BaseMessage, HumanMessage, AIMessage, SystemMessage

from app.domain.data.text_message_content_dto import TextMessageContentDTO
from app.domain.pyris_message import PyrisMessage, IrisMessageRole
Expand All @@ -10,23 +10,21 @@
def convert_iris_message_to_langchain_message(
iris_message: PyrisMessage,
) -> BaseMessage:
match iris_message.sender:
case IrisMessageRole.USER:
role = "human"
case IrisMessageRole.ASSISTANT:
role = "ai"
case IrisMessageRole.SYSTEM:
role = "system"
case _:
raise ValueError(f"Unknown message role: {iris_message.sender}")
if len(iris_message.contents) == 0:
raise ValueError("IrisMessage contents must not be empty")
message = iris_message.contents[0]
# Check if the message is of type TextMessageContentDTO
if not isinstance(message, TextMessageContentDTO):
raise ValueError("Message must be of type TextMessageContentDTO")
return BaseMessage(content=message.text_content, type=role)

match iris_message.sender:
case IrisMessageRole.USER:
return HumanMessage(content=message.text_content)
case IrisMessageRole.ASSISTANT:
return AIMessage(content=message.text_content)
case IrisMessageRole.SYSTEM:
return SystemMessage(content=message.text_content)
case _:
raise ValueError(f"Unknown message role: {iris_message.sender}")

def convert_langchain_message_to_iris_message(
base_message: BaseMessage,
Expand Down
11 changes: 7 additions & 4 deletions app/domain/__init__.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,14 @@
from .error_response_dto import IrisErrorResponseDTO
from .pipeline_execution_dto import PipelineExecutionDTO
from .pyris_message import PyrisMessage
from .pipeline_execution_settings_dto import PipelineExecutionSettingsDTO
from app.domain.tutor_chat.tutor_chat_pipeline_execution_dto import (
TutorChatPipelineExecutionDTO,
from .chat.chat_pipeline_execution_dto import ChatPipelineExecutionDTO
from .chat.chat_pipeline_execution_base_data_dto import ChatPipelineExecutionBaseDataDTO
from app.domain.chat.exercise_chat.exercise_chat_pipeline_execution_dto import (
ExerciseChatPipelineExecutionDTO,
)
from app.domain.tutor_chat.lecture_chat_pipeline_execution_dto import (
LectureChatPipelineExecutionDTO,
from app.domain.chat.course_chat.course_chat_pipeline_execution_dto import (
CourseChatPipelineExecutionDTO,
)
from .pyris_message import PyrisMessage, IrisMessageRole
from app.domain.data import image_message_content_dto
File renamed without changes.
16 changes: 16 additions & 0 deletions app/domain/chat/chat_pipeline_execution_base_data_dto.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
from typing import List, Optional

from pydantic import Field, BaseModel

from app.domain import PyrisMessage, PipelineExecutionSettingsDTO
from app.domain.data.user_dto import UserDTO
from app.domain.status.stage_dto import StageDTO


class ChatPipelineExecutionBaseDataDTO(BaseModel):
chat_history: List[PyrisMessage] = Field(alias="chatHistory", default=[])
user: Optional[UserDTO]
settings: Optional[PipelineExecutionSettingsDTO]
initial_stages: Optional[List[StageDTO]] = Field(
default=None, alias="initialStages"
)
16 changes: 16 additions & 0 deletions app/domain/chat/chat_pipeline_execution_dto.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
from typing import List, Optional

from pydantic import Field

from app.domain import PipelineExecutionDTO, PyrisMessage, PipelineExecutionSettingsDTO
from app.domain.data.user_dto import UserDTO
from app.domain.status.stage_dto import StageDTO


class ChatPipelineExecutionDTO(PipelineExecutionDTO):
chat_history: List[PyrisMessage] = Field(alias="chatHistory", default=[])
user: Optional[UserDTO]
settings: Optional[PipelineExecutionSettingsDTO]
initial_stages: Optional[List[StageDTO]] = Field(
default=None, alias="initialStages"
)
File renamed without changes.
15 changes: 15 additions & 0 deletions app/domain/chat/course_chat/course_chat_pipeline_execution_dto.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
from typing import Optional

from pydantic import Field

from ..chat_pipeline_execution_base_data_dto import ChatPipelineExecutionBaseDataDTO
from ..chat_pipeline_execution_dto import ChatPipelineExecutionDTO
from ...data.extended_course_dto import ExtendedCourseDTO
from ...data.metrics.competency_jol_dto import CompetencyJolDTO
from ...data.metrics.student_metrics_dto import StudentMetricsDTO


class CourseChatPipelineExecutionDTO(ChatPipelineExecutionDTO):
course: ExtendedCourseDTO
metrics: Optional[StudentMetricsDTO]
competency_jol: Optional[CompetencyJolDTO] = Field(None, alias="competencyJol")
7 changes: 7 additions & 0 deletions app/domain/chat/course_chat/course_chat_status_update_dto.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
from typing import Optional

from app.domain.status.status_update_dto import StatusUpdateDTO


class CourseChatStatusUpdateDTO(StatusUpdateDTO):
result: Optional[str] = None
Empty file.
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
from typing import Optional

from app.domain.chat.chat_pipeline_execution_dto import ChatPipelineExecutionDTO
from app.domain.data.course_dto import CourseDTO
from app.domain.data.programming_exercise_dto import ProgrammingExerciseDTO
from app.domain.data.programming_submission_dto import ProgrammingSubmissionDTO


class ExerciseChatPipelineExecutionDTO(ChatPipelineExecutionDTO):
submission: Optional[ProgrammingSubmissionDTO] = None
exercise: ProgrammingExerciseDTO
course: CourseDTO
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
from typing import Optional

from app.domain.status.status_update_dto import StatusUpdateDTO


class ExerciseChatStatusUpdateDTO(StatusUpdateDTO):
result: Optional[str] = None
Empty file.
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
from app.domain import ChatPipelineExecutionDTO
from app.domain.data.course_dto import CourseDTO


class LectureChatPipelineExecutionDTO(ChatPipelineExecutionDTO):
course: CourseDTO
25 changes: 25 additions & 0 deletions app/domain/data/competency_dto.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
from datetime import datetime
from enum import Enum
from typing import Optional

from pydantic import BaseModel, Field


class CompetencyTaxonomy(str, Enum):
REMEMBER = "REMEMBER"
UNDERSTAND = "UNDERSTAND"
APPLY = "APPLY"
ANALYZE = "ANALYZE"
EVALUATE = "EVALUATE"
CREATE = "CREATE"


class CompetencyDTO(BaseModel):
id: Optional[int] = None
title: Optional[str] = None
description: Optional[str] = None
taxonomy: Optional[CompetencyTaxonomy] = None
soft_due_date: Optional[datetime] = Field(
default=None, alias="softDueDate"
)
optional: Optional[bool] = None
6 changes: 3 additions & 3 deletions app/domain/data/course_dto.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
from typing import Optional

from pydantic import BaseModel
from pydantic import BaseModel, Field


class CourseDTO(BaseModel):
id: int
name: Optional[str] = None
description: Optional[str] = None
name: Optional[str]
description: Optional[str] = Field(None)
15 changes: 15 additions & 0 deletions app/domain/data/exam_dto.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
from datetime import datetime
from typing import Optional

from pydantic import BaseModel, Field


class ExamDTO(BaseModel):
id: int = Field(alias="id")
title: Optional[str] = Field(alias="title", default=None)
is_text_exam: bool = Field(alias="isTextExam", default=False)
start_date: Optional[datetime] = Field(alias="startDate", default=None)
end_date: Optional[datetime] = Field(alias="endDate", default=None)
publish_results_date: Optional[datetime] = Field(alias="publishResultsDate", default=None)
exam_student_review_start: Optional[datetime] = Field(alias="examStudentReviewStart", default=None)
exam_student_review_end: Optional[datetime] = Field(alias="examStudentReviewEnd", default=None)
50 changes: 50 additions & 0 deletions app/domain/data/exercise_with_submissions_dto.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
from datetime import datetime
from enum import Enum
from typing import Optional, List

from pydantic import BaseModel, Field

from app.domain.data.simple_submission_dto import SimpleSubmissionDTO


class ExerciseType(str, Enum):
PROGRAMMING = "PROGRAMMING"
QUIZ = "QUIZ"
MODELING = "MODELING"
TEXT = "TEXT"
FILE_UPLOAD = "FILE_UPLOAD"


class ExerciseMode(str, Enum):
INDIVIDUAL = "INDIVIDUAL"
TEAM = "TEAM"


class DifficultyLevel(str, Enum):
EASY = "EASY"
MEDIUM = "MEDIUM"
HARD = "HARD"


class IncludedInOverallScore(str, Enum):
INCLUDED_COMPLETELY = "INCLUDED_COMPLETELY"
INCLUDED_AS_BONUS = "INCLUDED_AS_BONUS"
NOT_INCLUDED = "NOT_INCLUDED"


class ExerciseWithSubmissionsDTO(BaseModel):
id: int = Field(alias="id")
title: str = Field(alias="title")
type: ExerciseType = Field(alias="type")
mode: ExerciseMode = Field(alias="mode")
max_points: Optional[float] = Field(alias="maxPoints", default=None)
bonus_points: Optional[float] = Field(alias="bonusPoints", default=None)
difficulty_level: Optional[DifficultyLevel] = Field(alias="difficultyLevel", default=None)
release_date: Optional[datetime] = Field(alias="releaseDate", default=None)
due_date: Optional[datetime] = Field(alias="dueDate", default=None)
inclusion_mode: Optional[IncludedInOverallScore] = Field(alias="inclusionMode", default=None)
presentation_score_enabled: Optional[bool] = Field(alias="presentationScoreEnabled", default=None)
submissions: List[SimpleSubmissionDTO] = Field(default=[])

class Config:
require_by_default = False
26 changes: 26 additions & 0 deletions app/domain/data/extended_course_dto.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
from typing import Optional, List
from datetime import datetime
from pydantic import BaseModel, Field

from app.domain.data.competency_dto import CompetencyDTO
from app.domain.data.exam_dto import ExamDTO
from app.domain.data.exercise_with_submissions_dto import ExerciseWithSubmissionsDTO
from app.domain.data.programming_exercise_dto import ProgrammingLanguage


class ExtendedCourseDTO(BaseModel):
id: int = Field(alias="id")
name: str = Field(alias="name", default=None)
description: Optional[str] = Field(alias="description", default=None)
start_time: Optional[datetime] = Field(alias="startTime", default=None)
end_time: Optional[datetime] = Field(alias="endTime", default=None)
default_programming_language: Optional[ProgrammingLanguage] = Field(alias="defaultProgrammingLanguage", default=None)
max_complaints: Optional[int] = Field(alias="maxComplaints", default=None)
max_team_complaints: Optional[int] = Field(alias="maxTeamComplaints", default=None)
max_complaint_time_days: Optional[int] = Field(alias="maxComplaintTimeDays", default=None)
max_request_more_feedback_time_days: Optional[int] = Field(alias="maxRequestMoreFeedbackTimeDays", default=None)
max_points: Optional[int] = Field(alias="maxPoints", default=None)
presentation_score: Optional[int] = Field(alias="presentationScore", default=None)
exercises: List[ExerciseWithSubmissionsDTO] = Field(alias="exercises", default=[])
exams: List[ExamDTO] = Field(alias="exams", default=[])
competencies: List[CompetencyDTO] = Field(alias="competencies", default=[])
13 changes: 13 additions & 0 deletions app/domain/data/lecture_dto.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
from datetime import datetime
from typing import List, Optional
from pydantic import BaseModel, Field

from app.domain.data.lecture_unit_dto import LectureUnitDTO

class PyrisLectureDTO(BaseModel):
id: int = Field(alias="id")
title: Optional[str] = Field(alias="title", default=None)
description: Optional[str] = Field(alias="description", default=None)
start_date: Optional[datetime] = Field(alias="startDate", default=None)
end_date: Optional[datetime] = Field(alias="endDate", default=None)
units: List[LectureUnitDTO] = Field(alias="units", default=[])
21 changes: 11 additions & 10 deletions app/domain/data/lecture_unit_dto.py
Original file line number Diff line number Diff line change
@@ -1,14 +1,15 @@
from typing import Optional

from pydantic import BaseModel, Field


class LectureUnitDTO(BaseModel):
to_update: bool = Field(alias="toUpdate")
base_url: str = Field(alias="artemisBaseUrl")
pdf_file_base64: str = Field(default="", alias="pdfFile")
lecture_unit_id: int = Field(alias="lectureUnitId")
lecture_unit_name: str = Field(default="", alias="lectureUnitName")
lecture_id: int = Field(alias="lectureId")
lecture_name: str = Field(default="", alias="lectureName")
course_id: int = Field(alias="courseId")
course_name: str = Field(default="", alias="courseName")
course_description: str = Field(default="", alias="courseDescription")
to_update: Optional[bool] = Field(alias="toUpdate", default=None)
pdf_file_base64: Optional[str] = Field(alias="pdfFile", default=None)
lecture_unit_id: Optional[int] = Field(alias="lectureUnitId", default=None)
lecture_unit_name: Optional[str] = Field(alias="lectureUnitName", default=None)
lecture_id: Optional[int] = Field(alias="lectureId", default=None)
lecture_name: Optional[str] = Field(alias="lectureName", default=None)
course_id: Optional[int] = Field(alias="courseId", default=None)
course_name: Optional[str] = Field(alias="courseName", default=None)
course_description: Optional[str] = Field(alias="courseDescription", default=None)
18 changes: 18 additions & 0 deletions app/domain/data/metrics/competency_information_dto.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
from pydantic import BaseModel, Field
from typing import Optional
from datetime import datetime

from app.domain.data.competency_dto import CompetencyTaxonomy


class CompetencyInformationDTO(BaseModel):
id: Optional[int] = None
title: Optional[str] = None
description: Optional[str] = None
taxonomy: Optional[CompetencyTaxonomy | str] = None
soft_due_date: Optional[datetime] = Field(None, alias="softDueDate")
optional: Optional[bool] = None
mastery_threshold: Optional[int] = Field(None, alias="masteryThreshold")

class Config:
populate_by_name = True
14 changes: 14 additions & 0 deletions app/domain/data/metrics/competency_jol_dto.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
from pydantic import BaseModel, Field
from typing import Optional
from datetime import datetime


class CompetencyJolDTO(BaseModel):
competency_id: Optional[int] = Field(None, alias="competencyId")
jol_value: Optional[int] = Field(None, alias="jolValue")
judgement_time: Optional[datetime] = Field(None, alias="judgementTime")
competency_progress: Optional[float] = Field(None, alias="competencyProgress")
competency_confidence: Optional[float] = Field(None, alias="competencyConfidence")

class Config:
populate_by_name = True
14 changes: 14 additions & 0 deletions app/domain/data/metrics/competency_progress_dto.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
# app/domain/data/metrics/competency_progress_dto.py

from typing import Optional
from pydantic import BaseModel, Field


class CompetencyProgressDTO(BaseModel):
competency_id: Optional[int] = Field(None, alias="competencyId")
progress: Optional[float] = None

confidence: Optional[float] = None

class Config:
populate_by_name = True
16 changes: 16 additions & 0 deletions app/domain/data/metrics/competency_student_metrics_dto.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
from typing import Dict, Set, Optional
from pydantic import BaseModel, Field
from app.domain.data.metrics.competency_information_dto import CompetencyInformationDTO
from app.domain.data.metrics.competency_jol_dto import CompetencyJolDTO


class CompetencyStudentMetricsDTO(BaseModel):
competency_information: Dict[int, CompetencyInformationDTO] = Field({}, alias="competencyInformation")
exercises: Dict[int, Set[int]] = Field({})
lecture_units: Dict[int, Set[int]] = Field({}, alias="lectureUnits")
progress: Dict[int, float] = Field({})
confidence: Dict[int, float] = Field({})
jol_values: Dict[int, CompetencyJolDTO] = Field({}, alias="jolValues")

class Config:
populate_by_name = True
10 changes: 10 additions & 0 deletions app/domain/data/metrics/exercise_student_metrics_dto.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
from typing import Optional, Dict, Set
from pydantic import BaseModel, Field


class ExerciseStudentMetricsDTO(BaseModel):
average_score: Dict[int, float] = Field({}, alias="averageScore")
score: Dict[int, float] = Field({})
average_latest_submission: Dict[int, float] = Field({}, alias="averageLatestSubmission")
latest_submission: Dict[int, float] = Field({}, alias="latestSubmission")
completed: Set[int] = Field({})
Loading

0 comments on commit d28a3c7

Please sign in to comment.