Skip to content

Commit

Permalink
feat: add Pydantic classes to validate assignment structure and busin…
Browse files Browse the repository at this point in the history
…ess rules
  • Loading branch information
lpm0073 committed Nov 29, 2023
1 parent c85f95d commit 33de272
Show file tree
Hide file tree
Showing 2 changed files with 71 additions and 2 deletions.
14 changes: 12 additions & 2 deletions grader/grader.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
import json
import os

from pydantic import BaseModel, Field, field_validator, model_validator
from pydantic import BaseModel, Field, ValidationError, field_validator, model_validator

from .exceptions import (
AGException,
Expand All @@ -13,6 +13,7 @@
InvalidResponseStructureError,
ResponseFailedError,
)
from .langchain import LCResponse


VALID_MESSAGE_TYPES = [
Expand All @@ -38,7 +39,7 @@ class Grade(BaseModel):
Subclasses should override the necessary methods to provide the grading logic.
"""

potential_points: float = Field(..., description="The maximum number of points that can be awarded.", gt=0)
potential_points: float = Field(100, description="The maximum number of points that can be awarded.", ge=0)
grade: float = Field(..., description="The number of points awarded.", ge=0)
message: str = Field(..., description="A result message to the student.")
message_type: str = Field(..., description="The type of result message.")
Expand Down Expand Up @@ -227,4 +228,13 @@ def grade(self):
return self.grade_response(e)
except IncorrectResponseTypeError as e:
return self.grade_response(e)

# this is an experimental usage of pydantic to validate the assignment
try:
LCResponse(**self.assignment)
except ValidationError as e:
error_text = str(e)
e = InvalidResponseStructureError(f"The assignment is not a valid LCResponse. error: {error_text}")
return self.grade_response(e)

return self.grade_response()
59 changes: 59 additions & 0 deletions grader/langchain.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
# -*- coding: utf-8 -*-
"""LangChain integration models"""

from typing import List, Optional

from pydantic import BaseModel, Field


class LCRequestMetaData(BaseModel):
"""LangChain request meta data"""

lambda_name: str = Field(..., alias="lambda")
model: str
end_point: str
temperature: float = Field(..., ge=0, le=1)
max_tokens: int = Field(..., gt=0)


class LCMessage(BaseModel):
"""LangChain message"""

content: str
additional_kwargs: dict
type: str
example: bool


class LCChatMemory(BaseModel):
"""LangChain chat memory"""

messages: List[LCMessage]

# @model_validator(mode="after")
# def validate_messages(self) -> "LCChatMemory":
# """Validate that chat memory contains at least 2 dicts"""
# if len(self.messages) < 2:
# raise ValueError("messages must contain at least 2 objects")
# return self


class LCBody(BaseModel):
"""LangChain body"""

chat_memory: LCChatMemory
output_key: Optional[str] = Field(None)
input_key: Optional[str] = Field(None)
return_messages: bool
human_prefix: str = Field("Human")
ai_prefix: str = Field("AI")
memory_key: str = Field("chat_history")
request_meta_data: LCRequestMetaData


class LCResponse(BaseModel):
"""LangChain Response Dict"""

is_base64_encoded: bool = Field(..., alias="isBase64Encoded")
status_code: int = Field(..., alias="statusCode", ge=200, le=599)
body: LCBody

0 comments on commit 33de272

Please sign in to comment.