Skip to content

Commit

Permalink
Merge pull request #1664 from watchdogpolska/dev_ext
Browse files Browse the repository at this point in the history
v1.5.06
  • Loading branch information
PiotrIw authored May 21, 2024
2 parents cd5bb14 + adf55bc commit 33c91c0
Show file tree
Hide file tree
Showing 11 changed files with 303 additions and 20 deletions.
2 changes: 1 addition & 1 deletion feder/__init__.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# PEP 396: The __version__ attribute's value SHOULD be a string.
__version__ = "1.5.05"
__version__ = "1.5.06"


# Compatibility to eg. django-rest-framework
Expand Down
9 changes: 8 additions & 1 deletion feder/letters/forms.py
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,14 @@ def get_html_body_with_footer(self, case=None):

def save(self, *args, **kwargs):
self.instance.body = html_to_text(self.cleaned_data["html_body"])
if "title" in self.changed_data or "html_body" in self.changed_data:
if (
not (
self.fields["html_body"].widget.attrs["readonly"]
or self.fields["title"].widget.attrs["readonly"]
)
and ("title" in self.changed_data or "html_body" in self.changed_data)
and not self.instance.author_institution
):
self.instance.author_user = self.user
if not self.instance.is_mass_draft() and "ai_evaluation" in self.changed_data:
update_letter_normalized_answers(self.instance.pk)
Expand Down
17 changes: 17 additions & 0 deletions feder/letters/migrations/0043_letter_only_one_or_none_author.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
# Generated by Django 4.2.13 on 2024-05-20 13:07

from django.db import migrations, models


class Migration(migrations.Migration):

dependencies = [
('letters', '0042_alter_letter_record'),
]

operations = [
migrations.AddConstraint(
model_name='letter',
constraint=models.CheckConstraint(check=models.Q(models.Q(('author_institution__isnull', True), ('author_user__isnull', False)), models.Q(('author_institution__isnull', False), ('author_user__isnull', True)), models.Q(('author_institution__isnull', True), ('author_user__isnull', True)), _connector='OR'), name='only_one_or_none_author'),
),
]
26 changes: 20 additions & 6 deletions feder/letters/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -209,12 +209,6 @@ class Letter(AbstractRecord):
objects = LetterManager()
objects_with_spam = LetterQuerySet.as_manager()

def is_spam_validated(self):
return self.is_spam in (Letter.SPAM.spam, Letter.SPAM.non_spam)

def is_mass_draft(self):
return self.is_draft and self.message_type == self.MESSAGE_TYPES.mass_draft

class Meta:
verbose_name = _("Letter")
verbose_name_plural = _("Letters")
Expand All @@ -224,6 +218,26 @@ class Meta:
("can_filter_eml", _("Can filter eml")),
("recognize_letter", _("Can recognize letter")),
)
constraints = [
models.CheckConstraint(
check=(
models.Q(author_user__isnull=False, author_institution__isnull=True)
| models.Q(
author_user__isnull=True, author_institution__isnull=False
)
| models.Q(
author_user__isnull=True, author_institution__isnull=True
)
),
name="only_one_or_none_author",
),
]

def is_spam_validated(self):
return self.is_spam in (Letter.SPAM.spam, Letter.SPAM.non_spam)

def is_mass_draft(self):
return self.is_draft and self.message_type == self.MESSAGE_TYPES.mass_draft

def delete(self, *args, **kwargs):
self.record.delete() # Delete the associated Record instance
Expand Down
12 changes: 4 additions & 8 deletions feder/llm_evaluation/admin.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ class LlmLetterRequestAdmin(admin.ModelAdmin):
date_hierarchy = "created"
list_display = (
"id",
"name",
"evaluated_letter",
"letter_id",
"engine_name",
Expand All @@ -27,10 +28,7 @@ class LlmLetterRequestAdmin(admin.ModelAdmin):
"get_time_used",
"created",
)
list_filter = (
"engine_name",
"status",
)
list_filter = ("engine_name", "status", "name")
actions = []

def has_delete_permission(self, request, obj=None):
Expand Down Expand Up @@ -61,17 +59,15 @@ class LlmMonitoringRequestAdmin(admin.ModelAdmin):
date_hierarchy = "created"
list_display = (
"id",
"name",
"evaluated_monitoring",
"engine_name",
"status",
"get_cost",
"get_time_used",
"created",
)
list_filter = (
"engine_name",
"status",
)
list_filter = ("engine_name", "status", "name")
actions = []

def has_delete_permission(self, request, obj=None):
Expand Down
2 changes: 1 addition & 1 deletion feder/llm_evaluation/llm_tools.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ def get_llm_response(prompt, prompt_kwargs_dict):
openai_api_key=settings.OPENAI_API_KEY,
openai_api_version=settings.OPENAI_API_VERSION,
azure_endpoint=settings.AZURE_ENDPOINT,
deployment_name=settings.OPENAI_API_DEPLOYMENT_NAME,
deployment_name=settings.OPENAI_API_ENGINE_35,
temperature=settings.OPENAI_API_TEMPERATURE,
)
chain = prompt | model | StrOutputParser()
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
# Generated by Django 4.2.13 on 2024-05-17 17:17

from django.db import migrations, models


class Migration(migrations.Migration):

dependencies = [
('llm_evaluation', '0008_alter_llmmonthlycost_options'),
]

operations = [
migrations.AddField(
model_name='llmletterrequest',
name='args',
field=models.JSONField(blank=True, null=True, verbose_name='Arguments'),
),
migrations.AddField(
model_name='llmletterrequest',
name='name',
field=models.CharField(blank=True, max_length=100, null=True, verbose_name='Name'),
),
migrations.AddField(
model_name='llmmonitoringrequest',
name='args',
field=models.JSONField(blank=True, null=True, verbose_name='Arguments'),
),
migrations.AddField(
model_name='llmmonitoringrequest',
name='name',
field=models.CharField(blank=True, max_length=100, null=True, verbose_name='Name'),
),
]
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
# Generated by Django 4.2.13 on 2024-05-20 11:06

from django.db import migrations, models


class Migration(migrations.Migration):

dependencies = [
('llm_evaluation', '0009_llmletterrequest_args_llmletterrequest_name_and_more'),
]

operations = [
migrations.AlterField(
model_name='llmletterrequest',
name='token_usage',
field=models.JSONField(blank=True, null=True, verbose_name='LLM Engine token usage'),
),
migrations.AlterField(
model_name='llmmonitoringrequest',
name='token_usage',
field=models.JSONField(blank=True, null=True, verbose_name='LLM Engine token usage'),
),
]
35 changes: 33 additions & 2 deletions feder/llm_evaluation/models.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import inspect
import json
import logging
import time
Expand All @@ -7,7 +8,6 @@
from django.db.models.functions import Substr
from django.utils import timezone
from django.utils.translation import gettext_lazy as _
from jsonfield import JSONField
from langchain.schema.output_parser import StrOutputParser
from langchain.text_splitter import TokenTextSplitter
from langchain_community.callbacks import get_openai_callback
Expand Down Expand Up @@ -44,6 +44,10 @@ class LlmRequest(TimeStampedModel):
(2, "done", _("Done")),
(3, "failed", _("Failed")),
)
name = models.CharField(
max_length=100, verbose_name=_("Name"), null=True, blank=True
)
args = models.JSONField(verbose_name=_("Arguments"), null=True, blank=True)
engine_name = models.CharField(
max_length=20, verbose_name=_("LLM Engine name"), null=True, blank=True
)
Expand All @@ -54,7 +58,7 @@ class LlmRequest(TimeStampedModel):
response = models.TextField(
verbose_name=_("LLM Engine response"), null=True, blank=True
)
token_usage = JSONField(
token_usage = models.JSONField(
verbose_name=_("LLM Engine token usage"), null=True, blank=True
)
objects = LLmRequestQuerySet.as_manager()
Expand Down Expand Up @@ -165,6 +169,8 @@ def categorize_letter(cls, letter):
monitoring_response=texts[0],
)
letter_llm_request = cls.objects.create(
name=inspect.currentframe().f_code.co_name,
args={"letter_pk": letter.pk},
evaluated_letter=letter,
engine_name=llm_engine,
request_prompt=final_prompt,
Expand Down Expand Up @@ -270,6 +276,8 @@ def get_normalized_answers(cls, letter):
monitoring_response=text,
)
letter_llm_request = cls.objects.create(
name=inspect.currentframe().f_code.co_name,
args={"letter_pk": letter.pk},
evaluated_letter=letter,
engine_name=llm_engine,
request_prompt=final_prompt,
Expand Down Expand Up @@ -345,6 +353,25 @@ def categorize_answer(self, letter, question_number):
+ f' "{question_number}"'
)
return
categories_update_time = (
letter.case.monitoring.get_categories_update_time_for_question(
question_number
)
)
categorization_already_done = self.objects.filter(
name=inspect.currentframe().f_code.co_name,
evaluated_letter=letter,
args__question_number=question_number,
created__gt=categories_update_time,
).first()
if categorization_already_done:
logger.info(
f"Skipping categorization for letter {letter.pk} and question"
+ f' "{question_number}" as already done: '
+ f"{categorization_already_done.args} at "
+ f"{categorization_already_done.created}."
)
return
question = question_and_answer_dict[NORMALIZED_RESPONSE_QUESTION_KEY]
answer = question_and_answer_dict[NORMALIZED_RESPONSE_ANSWER_KEY]
answer_categories = (
Expand Down Expand Up @@ -383,6 +410,8 @@ def categorize_answer(self, letter, question_number):
logger.warning(message)
return
letter_llm_request = self.objects.create(
name=inspect.currentframe().f_code.co_name,
args={"letter_pk": letter.pk, "question_number": question_number},
evaluated_letter=letter,
engine_name=llm_engine,
request_prompt=prompt,
Expand Down Expand Up @@ -443,6 +472,8 @@ def get_response_normalized_template(cls, monitoring):
)
llm_engine = settings.OPENAI_API_ENGINE_35
monitoring_llm_request = cls.objects.create(
name=inspect.currentframe().f_code.co_name,
args={"monitoring_pk": monitoring.pk},
evaluated_monitoring=monitoring,
engine_name=llm_engine,
request_prompt=final_prompt,
Expand Down
Loading

0 comments on commit 33c91c0

Please sign in to comment.