Skip to content

Commit

Permalink
create threads from battles and battle groups
Browse files Browse the repository at this point in the history
  • Loading branch information
catgirlinspace committed Nov 30, 2023
1 parent 933a02e commit 7fd8118
Show file tree
Hide file tree
Showing 10 changed files with 163 additions and 13 deletions.
69 changes: 67 additions & 2 deletions assistant/data.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,12 @@
from django.db.models import Prefetch
from openai import OpenAI

from battles.models import Player, Battle
from battles.models import Player, Battle, BattleGroup

client = OpenAI(api_key=settings.OPENAI_API_KEY)


def upload_data_to_openai(user):
def upload_user_battles_to_openai(user):
player_query = Player.objects.select_related(
"title_adjective__string",
"title_subject__string",
Expand Down Expand Up @@ -59,3 +59,68 @@ def upload_data_to_openai(user):
purpose='assistants'
)
return openai_file


def upload_battle_to_openai(battle: Battle):
battle_array = [json.dumps(battle.to_gpt_dict()) + '\n']
temp_file = StringIO("")
temp_file.writelines(battle_array)
temp_file.seek(0)
temp_file = BytesIO(temp_file.read().encode('utf-8'))
temp_file.seek(0)
openai_file = client.files.create(
file=temp_file,
purpose='assistants'
)
return openai_file


def upload_battle_group_to_openai(battle_group: BattleGroup):
player_query = Player.objects.select_related(
"title_adjective__string",
"title_subject__string",
"nameplate_background",
"nameplate_badge_1__description",
"nameplate_badge_2__description",
"nameplate_badge_3__description",
"weapon__name",
"weapon__sub__name",
"weapon__special__name",
"head_gear__gear__name",
"head_gear__primary_ability__name",
"head_gear__secondary_ability_1__name",
"head_gear__secondary_ability_2__name",
"head_gear__secondary_ability_3__name",
"clothing_gear__gear__name",
"clothing_gear__primary_ability__name",
"clothing_gear__secondary_ability_1__name",
"clothing_gear__secondary_ability_2__name",
"clothing_gear__secondary_ability_3__name",
"shoes_gear__gear__name",
"shoes_gear__primary_ability__name",
"shoes_gear__secondary_ability_1__name",
"shoes_gear__secondary_ability_2__name",
"shoes_gear__secondary_ability_3__name",
)
player_prefetch = Prefetch(
'teams__players',
queryset=player_query,
)
battles = battle_group.battles.select_related("vs_stage__name").prefetch_related("awards__name",
player_prefetch).order_by(
'-played_time')
battle_array = []
battle: Battle
for battle in battles:
battle_data = battle.to_gpt_dict()
battle_array.append(json.dumps(battle_data) + '\n')
temp_file = StringIO("")
temp_file.writelines(battle_array)
temp_file.seek(0)
temp_file = BytesIO(temp_file.read().encode('utf-8'))
temp_file.seek(0)
openai_file = client.files.create(
file=temp_file,
purpose='assistants'
)
return openai_file
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
# Generated by Django 4.2.7 on 2023-11-30 01:47

import django.db.models.deletion
from django.db import migrations, models


class Migration(migrations.Migration):
dependencies = [
('contenttypes', '0002_remove_content_type_name'),
('assistant', '0004_thread_runner_machine_id'),
]

operations = [
migrations.AddField(
model_name='thread',
name='content_type',
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE,
to='contenttypes.contenttype'),
),
migrations.AddField(
model_name='thread',
name='object_id',
field=models.PositiveIntegerField(blank=True, null=True),
),
migrations.AddIndex(
model_name='thread',
index=models.Index(fields=['content_type', 'object_id'], name='assistant_t_content_9f2484_idx'),
),
]
10 changes: 10 additions & 0 deletions assistant/models.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
from django.contrib.contenttypes.fields import GenericForeignKey
from django.contrib.contenttypes.models import ContentType
from django.db import models


Expand All @@ -15,3 +17,11 @@ class Status(models.TextChoices):
initial_message = models.TextField(default='')
status = models.CharField(blank=True, choices=Status.choices, max_length=25)
runner_machine_id = models.CharField(blank=True, max_length=20)
content_type = models.ForeignKey(ContentType, on_delete=models.CASCADE, blank=True, null=True)
object_id = models.PositiveIntegerField(blank=True, null=True)
content_object = GenericForeignKey("content_type", "object_id")

class Meta:
indexes = [
models.Index(fields=["content_type", "object_id"]),
]
10 changes: 8 additions & 2 deletions assistant/runner.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,8 @@
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'splashcat.settings')
django.setup()

from assistant.data import upload_data_to_openai
from battles.models import Battle, BattleGroup
from assistant.data import upload_user_battles_to_openai, upload_battle_to_openai, upload_battle_group_to_openai
from assistant.models import Thread

client = OpenAI(api_key=settings.OPENAI_API_KEY)
Expand All @@ -26,7 +27,12 @@

initial_prompt = thread.initial_message

openai_file = upload_data_to_openai(thread.creator)
if thread.content_type.model_class() == Battle:
openai_file = upload_battle_to_openai(thread.content_object)
elif thread.content_type.model_class() == BattleGroup:
openai_file = upload_battle_group_to_openai(thread.content_object)
else:
openai_file = upload_user_battles_to_openai(thread.creator)

thread.openai_file_id = openai_file.id
thread.status = thread.Status.CREATED
Expand Down
2 changes: 1 addition & 1 deletion assistant/templates/assistant/create_thread.html
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ <h1 class="text-2xl font-splatoon1">
{% block title %}Create Thread{% endblock %}
</h1>

<form action="{% url 'assistant:create_thread' %}" method="post" class="form-css">
<form action="" method="post" class="form-css">
{% csrf_token %}

{{ form.as_div }}
Expand Down
1 change: 1 addition & 0 deletions assistant/urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,4 +9,5 @@
path('threads/<int:thread_id>/messages/', views.get_thread_messages, name='get_thread_messages'),
path('threads/<int:thread_id>/messages/send/', views.send_message_to_thread, name='send_message_to_thread'),
path('threads/create/', views.create_thread, name='create_thread'),
path('threads/create/<str:app_label>/<str:model_name>/<int:object_id>/', views.create_thread, name='create_thread'),
]
26 changes: 24 additions & 2 deletions assistant/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,17 @@
import django_htmx.http
from django.conf import settings
from django.contrib.auth.decorators import login_required
from django.contrib.contenttypes.models import ContentType
from django.db import transaction
from django.http import HttpResponseBadRequest
from django.http import HttpResponseBadRequest, HttpResponseNotFound
from django.shortcuts import redirect, get_object_or_404, render
from django.views.decorators.http import require_POST
from openai import OpenAI

from assistant import orchestrator
from assistant.forms import CreateThreadForm
from assistant.models import Thread
from battles.models import Battle, BattleGroup
from users.models import User, SponsorshipTiers

client = OpenAI(api_key=settings.OPENAI_API_KEY)
Expand Down Expand Up @@ -40,7 +42,25 @@ def threads(request):
@login_required
@require_sponsor_tier
@transaction.atomic
def create_thread(request):
def create_thread(request, app_label, model_name, object_id):
found_object: None = None
if app_label:
if not model_name and not object_id:
return HttpResponseNotFound()
content_type = ContentType.objects.get(app_label__iexact=app_label, model__iexact=model_name)
found_object = content_type.get_object_for_this_type(pk=object_id)

if content_type.model_class() is Battle:
found_object: Battle
if found_object.uploader_id != request.user.id:
return HttpResponseBadRequest()
elif content_type.model_class() is BattleGroup:
found_object: BattleGroup
if found_object.creator_id != request.user.id:
return HttpResponseBadRequest()
else:
return HttpResponseBadRequest()

if request.method == "GET":
form = CreateThreadForm()
return render(request, "assistant/create_thread.html", {
Expand All @@ -54,6 +74,8 @@ def create_thread(request):
openai_thread = client.beta.threads.create()
thread = Thread(creator=request.user, openai_thread_id=openai_thread.id, status=Thread.Status.PENDING,
initial_message=form.cleaned_data['initial_message'])
if found_object:
thread.content_object = found_object
thread.save()

machine_id = orchestrator.schedule_machine(thread)
Expand Down
5 changes: 5 additions & 0 deletions battles/templates/battles/groups/view.html
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,11 @@ <h1 class="font-splatoon1 text-3xl pb-2">
</button>
</h1>

{% if battle_group.creator_id == user.id and user.has_splashcat_assistant %}
<a href="{% url 'assistant:create_thread' 'battles' 'BattleGroup' battle_group.id %}"
class="bg-purple-800 p-4 rounded w-fit max-h-fit block">Create Assistant Thread</a>
{% endif %}

<h2 class="font-splatoon1 text-xl">Creator</h2>
{% include "users/includes/user-link.html" with user=battle_group.creator show_splashtag=True %}

Expand Down
20 changes: 14 additions & 6 deletions battles/templates/battles/view_battle.html
Original file line number Diff line number Diff line change
Expand Up @@ -80,12 +80,20 @@ <h1 class="text-3xl font-splatoon1">
</div>
</a>

{% if battle.gpt_description_generated %}
<details class="bg-purple-900 p-4 rounded w-fit max-w-prose group">
<summary class="group-open:border-b-2 group-open:mb-2 group-open:pb-1">AI Battle Description</summary>
{{ battle.gpt_description }}
</details>
{% endif %}
<div class="flex flex-row gap-4 flex-wrap">
{% if battle.gpt_description_generated %}
<details class="bg-purple-800 p-4 rounded w-fit max-w-prose group">
<summary class="group-open:border-b-2 group-open:mb-2 group-open:pb-1">AI Battle Description</summary>
{{ battle.gpt_description }}
</details>
{% endif %}
{% if battle.uploader_id == user.id and user.has_splashcat_assistant %}
<div>
<a href="{% url 'assistant:create_thread' 'battles' 'Battle' battle.id %}"
class="bg-purple-800 p-4 rounded w-fit block">Create Assistant Thread</a>
</div>
{% endif %}
</div>

<div class="flex flex-row flex-wrap gap-4 items-center">
<div class="flex flex-wrap gap-4 py-2">
Expand Down
4 changes: 4 additions & 0 deletions users/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,10 @@ def sponsor_tiers(self) -> dict[SponsorshipTiers, bool]:
sponsorship_amount = 0
return {tier: sponsorship_amount >= amount for tier, amount in sponsorship_tier_costs.items()}

@property
def has_splashcat_assistant(self):
return self.sponsor_tiers[SponsorshipTiers.X_PONSOR]

def get_full_name(self):
return self.display_name.strip()

Expand Down

0 comments on commit 7fd8118

Please sign in to comment.