Skip to content
This repository was archived by the owner on Dec 3, 2025. It is now read-only.
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
## open ai chat backend configuration and information

## Module description

Enter a module description here.

## Features

- [ ] This module includes migrations.
- [ ] This module includes environment variables.
- [ ] This module requires manual configurations.
- [ ] This module can be configured with module options.

## Environment variables

```properties
ENV_VAR="value"
```

## 3rd party setup

Create account...

Include screenshots if possible here.

## Dependencies

Link to the READMEs of the packages that you used in this module.

Dependencies used:
- package-name and link to the package

## API details

| Api Name | Param | Description |
| ------------------------------ |:------------:|:---------------------------------------------------------------|
| `/modules/module-name/endpoint/` | object `{something: 'string'}` | Description here.|
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
from django.contrib import admin
from .models import Conversation, Message, OpenAIConfig, UserConfig


class MessageInline(admin.TabularInline):
model = Message
extra = 0
readonly_fields = ('conversation', 'role', 'content', 'response','created_at', 'updated_at')
fieldsets = (
(None, {
'fields': ('conversation', 'role', 'content', 'response')
}),
('Dates', {
'fields': ('created_at', 'updated_at'),
}),
)

class ConversationAdmin(admin.ModelAdmin):
list_display = ('session', 'user', 'summary', 'created_at', 'updated_at')
search_fields = ('session', 'user', 'summary', 'created_at', 'updated_at')
readonly_fields = ('created_at', 'updated_at')
ordering = ('-created_at',)
list_filter = ('session', 'user', 'summary', 'created_at', 'updated_at')
fieldsets = (
(None, {
'fields': ('session', 'user', 'summary')
}),
('Dates', {
'fields': ('created_at', 'updated_at'),
}),
)
inlines = [
MessageInline,
]
admin.site.register(Conversation, ConversationAdmin)

class MessageAdmin(admin.ModelAdmin):
list_display = ('conversation', 'role', 'content', 'response', 'created_at', 'updated_at')
search_fields = ('conversation', 'role', 'content', 'response', 'created_at', 'updated_at')
readonly_fields = ('created_at', 'updated_at')
ordering = ('-created_at',)
list_filter = ('conversation', 'role', 'content', 'response', 'created_at', 'updated_at')
fieldsets = (
(None, {
'fields': ('conversation', 'role', 'content', 'response')
}),
('Dates', {
'fields': ('created_at', 'updated_at'),
}),
)
admin.site.register(Message, MessageAdmin)


class OpenAIConfigAdmin(admin.ModelAdmin):
list_display = ('model', 'max_tokens', 'use_context', 'context_length', 'only_questions_in_context', 'summarize_context', 'initial_context', 'is_active', 'global_config', 'created_at', 'updated_at')
search_fields = ('model', 'max_tokens', 'use_context', 'context_length', 'only_questions_in_context', 'summarize_context', 'initial_context', 'is_active', 'global_config', 'created_at', 'updated_at')
readonly_fields = ('created_at', 'updated_at')
ordering = ('-created_at',)
list_filter = ('model', 'max_tokens', 'use_context', 'context_length', 'only_questions_in_context', 'summarize_context', 'initial_context', 'is_active', 'global_config', 'created_at', 'updated_at')
fieldsets = (
(None, {
'fields': ('model', 'max_tokens', 'use_context', 'context_length', 'only_questions_in_context', 'summarize_context', 'initial_context', 'is_active', 'global_config')
}),
('Dates', {
'fields': ('created_at', 'updated_at'),
}),
)

admin.site.register(OpenAIConfig, OpenAIConfigAdmin)


class UserConfigAdmin(admin.ModelAdmin):
list_display = ('user', 'config', 'created_at', 'updated_at')
search_fields = ('user', 'config', 'created_at', 'updated_at')
readonly_fields = ('created_at', 'updated_at')
ordering = ('-created_at',)
list_filter = ('user', 'config', 'created_at', 'updated_at')
fieldsets = (
(None, {
'fields': ('user', 'config')
}),
('Dates', {
'fields': ('created_at', 'updated_at'),
}),
)

admin.site.register(UserConfig, UserConfigAdmin)
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
# Generated by Django 3.2.23 on 2023-12-12 22:43

from django.conf import settings
from django.db import migrations, models
import django.db.models.deletion
import uuid


class Migration(migrations.Migration):

initial = True

dependencies = [
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
]

operations = [
migrations.CreateModel(
name='Conversation',
fields=[
('session', models.CharField(blank=True, max_length=255, null=True)),
('uuid', models.UUIDField(default=uuid.uuid4, editable=False, primary_key=True, serialize=False)),
('summary', models.TextField(blank=True, null=True)),
('created_at', models.DateTimeField(auto_now_add=True)),
('updated_at', models.DateTimeField(auto_now=True)),
('user', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)),
],
),
migrations.CreateModel(
name='Message',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('role', models.CharField(blank=True, max_length=255, null=True)),
('content', models.TextField()),
('response', models.TextField(blank=True, null=True)),
('created_at', models.DateTimeField(auto_now_add=True)),
('updated_at', models.DateTimeField(auto_now=True)),
('conversation', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='open_ai_chat.conversation')),
],
),
]
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
# Generated by Django 3.2.23 on 2023-12-23 04:32

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


class Migration(migrations.Migration):

dependencies = [
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
('open_ai_chat', '0001_initial'),
]

operations = [
migrations.CreateModel(
name='OpenAIConfig',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('model', models.CharField(blank=True, choices=[('gpt-3.5-turbo', 'gpt-3.5-turbo'), ('gpt-3.5-turbo-1106', 'gpt-3.5-turbo-1106'), ('gpt-3.5-turbo-16k', 'gpt-3.5-turbo-16k'), ('gpt-4-0314', 'gpt-4-0314')], max_length=255, null=True)),
('max_tokens', models.IntegerField(blank=True, default=1000, null=True)),
('use_context', models.BooleanField(default=True, help_text='Use context from previous messages')),
('context_length', models.IntegerField(blank=True, default=3, help_text='Number of previous messages to use as context', null=True)),
('only_questions_in_context', models.BooleanField(default=False, help_text='Only use questions in context')),
('summarize_context', models.BooleanField(default=True, help_text='use summary as context')),
('initial_context', models.TextField(blank=True, help_text='Initial context to use e.g. You are a crowdbotics assistant.', null=True)),
('is_active', models.BooleanField(default=True, help_text='Is this config active')),
('global_config', models.BooleanField(default=False, help_text='Is this config global')),
('created_at', models.DateTimeField(auto_now_add=True)),
('updated_at', models.DateTimeField(auto_now=True)),
],
options={
'verbose_name': 'OpenAI Config',
'verbose_name_plural': 'OpenAI Configs',
'unique_together': {('is_active', 'global_config')},
},
),
migrations.CreateModel(
name='UserConfig',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('created_at', models.DateTimeField(auto_now_add=True)),
('updated_at', models.DateTimeField(auto_now=True)),
('config', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='open_ai_chat.openaiconfig')),
('user', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)),
],
),
]
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
import uuid
from django.db import models
from django.conf import settings

class Conversation(models.Model):
session = models.CharField(max_length=255, null=True, blank=True)
user = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE, null=True, blank=True)
uuid = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
summary = models.TextField(null=True, blank=True)
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(auto_now=True)

def __str__(self) -> str:
return f"{self.session}"


class Message(models.Model):
conversation = models.ForeignKey(Conversation, on_delete=models.CASCADE, null=True, blank=True)
role = models.CharField(max_length=255, null=True, blank=True)
content = models.TextField()
response = models.TextField(null=True, blank=True)
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(auto_now=True)

def __str__(self) -> str:
return f"{self.id} - {self.content}"


class OpenAIConfig(models.Model):

MODELS = [
("gpt-3.5-turbo", "gpt-3.5-turbo"),
("gpt-3.5-turbo-1106", "gpt-3.5-turbo-1106"),
("gpt-3.5-turbo-16k", "gpt-3.5-turbo-16k"),
("gpt-4-0314", "gpt-4-0314")
]

model = models.CharField(max_length=255, null=True, blank=True, choices=MODELS)
max_tokens = models.IntegerField(null=True, blank=True, default=1000)
use_context = models.BooleanField(default=True, help_text="Use context from previous messages")
context_length = models.IntegerField(null=True, blank=True, default=3, help_text="Number of previous messages to use as context")
only_questions_in_context = models.BooleanField(default=False, help_text="Only use questions in context")
summarize_context = models.BooleanField(default=True, help_text="use summary as context")
initial_context = models.TextField(null=True, blank=True, help_text="Initial context to use e.g. You are a crowdbotics assistant.")
is_active = models.BooleanField(default=True, help_text="Is this config active")
global_config = models.BooleanField(default=False, help_text="Is this config global")
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(auto_now=True)

def __str__(self) -> str:
return f"{self.id} - {self.model}"

class Meta:
verbose_name = "OpenAI Config"
verbose_name_plural = "OpenAI Configs"


class UserConfig(models.Model):
user = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE, null=True, blank=True)
config = models.ForeignKey(OpenAIConfig, on_delete=models.CASCADE, null=True, blank=True)
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(auto_now=True)
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
from rest_framework import serializers

# your serializer here
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import os
from openai import OpenAI as core_openai

class OpenAI:
client = None
model = None
max_tokens = 1000
def __init__(self, api_key=None, model='gpt-3.5-turbo'):
self.api_key = api_key or os.environ.get("OPENAI_API_KEY", "")
self.client = core_openai(
api_key=self.api_key,
)
self.model = model

# todo: calculate number of tokens based on question length + context length + model
# todo: add context to the question

def ask(self, question, context=[]):
messages = context
messages.append({"role": "user", "content": question})
messages.append({
"role": "system",
"content": "follow the rules: rule 1. short 2-3 liner chat type answers. rule 2. you must iclude a summary at the end or every message, summary should include context from provided system message, current question and answer to be used as context for next message.",
})
response = self.client.chat.completions.create(
messages=messages,
model=self.model,
max_tokens=self.max_tokens,
)
return response.choices[0].message.content
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
from django.urls import path, include
from rest_framework import routers
from .viewsets import ConversationViewSet

router = routers.DefaultRouter()
router.register(r'chat', ConversationViewSet, basename='openai-chat')
urlpatterns = [
path('', include(router.urls)),
]
Loading