MGLDZM commited on
Commit
e2e403d
·
1 Parent(s): 75d9414
main.py CHANGED
@@ -4,7 +4,7 @@ from fastapi.security import HTTPBasic, HTTPBasicCredentials
4
  import os, json
5
  import time
6
  from hashlib import sha256
7
- from modules import model, oauth, security, log_module, llm, token_counter, chat_functions
8
  from fastapi.staticfiles import StaticFiles
9
  from fastapi.templating import Jinja2Templates
10
  from datetime import datetime
@@ -14,8 +14,6 @@ app = FastAPI(docs_url=None, redoc_url=None)
14
  app.mount("/static", StaticFiles(directory="static"), name="static")
15
  templates = Jinja2Templates(directory="templates")
16
 
17
- users = json.loads(str(os.getenv("USER_KEYS")).replace("\n", ""))
18
-
19
  fecha_unix = str(int(time.time()))
20
  log_module.log_write("master", "iniciado", "-")
21
 
@@ -41,7 +39,7 @@ async def main_page(request: Request, user = Depends(model.User.find_from_cookie
41
  ########################## SECURITY ##########################
42
  @app.get("/login", response_class=HTMLResponse)
43
  async def login(request: Request):
44
- ret = templates.TemplateResponse("iniciar_sesion.html", {"request": request, "redirecturi": oauth.OAUTH_REDIRECT})
45
  ret.delete_cookie("token")
46
  return ret
47
 
 
4
  import os, json
5
  import time
6
  from hashlib import sha256
7
+ from modules import model, oauth, security, log_module, llm, chat_functions, settings
8
  from fastapi.staticfiles import StaticFiles
9
  from fastapi.templating import Jinja2Templates
10
  from datetime import datetime
 
14
  app.mount("/static", StaticFiles(directory="static"), name="static")
15
  templates = Jinja2Templates(directory="templates")
16
 
 
 
17
  fecha_unix = str(int(time.time()))
18
  log_module.log_write("master", "iniciado", "-")
19
 
 
39
  ########################## SECURITY ##########################
40
  @app.get("/login", response_class=HTMLResponse)
41
  async def login(request: Request):
42
+ ret = templates.TemplateResponse("iniciar_sesion.html", {"request": request, "redirecturi": settings.OAUTH_REDIRECT})
43
  ret.delete_cookie("token")
44
  return ret
45
 
modules/llm.py CHANGED
@@ -3,19 +3,19 @@ import os, json, time
3
  from hashlib import sha256
4
  from fastapi import HTTPException
5
  from openai import OpenAI
 
6
 
7
-
8
- from . import log_module, error_map, chat_functions as tools
9
  from typing import TYPE_CHECKING
10
  if TYPE_CHECKING:
11
  from . import model
12
 
13
 
14
- OPENAI_API_KEY=os.environ['OPENAI_API_KEY']
15
 
16
- gptmodel = "gpt-3.5-turbo-1106"
17
 
18
- encoding = tiktoken.encoding_for_model(llm.gptmodel)
 
 
19
 
20
 
21
  def ejecutar(body: "model.Body", user: "model.User"):
@@ -23,12 +23,12 @@ def ejecutar(body: "model.Body", user: "model.User"):
23
 
24
  try:
25
  client = OpenAI(
26
- api_key=OPENAI_API_KEY,
27
  timeout=30.0,
28
  max_retries=3
29
  )
30
  generated = client.chat.completions.create(
31
- model=gptmodel,
32
  messages=temp_messages,
33
  temperature=user.configs.temperature,
34
  frequency_penalty=user.configs.frequency_penalty,
 
3
  from hashlib import sha256
4
  from fastapi import HTTPException
5
  from openai import OpenAI
6
+ import tiktoken
7
 
8
+ from . import log_module, error_map, chat_functions as tools, settings
 
9
  from typing import TYPE_CHECKING
10
  if TYPE_CHECKING:
11
  from . import model
12
 
13
 
 
14
 
 
15
 
16
+
17
+
18
+ encoding = tiktoken.encoding_for_model(settings.GPT_MODEL)
19
 
20
 
21
  def ejecutar(body: "model.Body", user: "model.User"):
 
23
 
24
  try:
25
  client = OpenAI(
26
+ api_key=settings.OPENAI_API_KEY,
27
  timeout=30.0,
28
  max_retries=3
29
  )
30
  generated = client.chat.completions.create(
31
+ model=settings.GPT_MODEL,
32
  messages=temp_messages,
33
  temperature=user.configs.temperature,
34
  frequency_penalty=user.configs.frequency_penalty,
modules/model.py CHANGED
@@ -2,24 +2,23 @@ import os
2
  from pymongo.mongo_client import MongoClient
3
  from pymongo.server_api import ServerApi
4
  from fastapi import Request
5
- from . import log_module, security, token_counter
6
  from datetime import timezone, datetime, timedelta
7
- from pydantic import BaseModel
8
  from typing import List, Dict
9
  import tiktoken
 
 
10
 
11
 
12
- MONGO_URL = os.environ.get("MONGO_URL", None)
13
- MONGO_PWD = os.environ.get("MONGO_PWD", None)
14
- MONGO_USR = os.environ.get("MONGO_USR", None)
15
- #uri = f"mongodb+srv://{MONGO_USR}:{MONGO_PWD}@{MONGO_URL}/?retryWrites=true&w=majority"
16
- uri = "mongodb://localhost:27017"
17
- client = MongoClient(uri, server_api=ServerApi('1'))
18
- user_table = client.ChatDB.users
19
- sess_table = client.ChatDB.sessions
20
 
21
  tz = timezone(timedelta(hours=-4))
22
-
23
 
24
  def count_tokens_on_message(args):
25
  token_count = 0
@@ -61,13 +60,37 @@ class Chat(BaseModel):
61
  def new_msg(self):
62
  return Message(role="", content="")
63
 
64
- class SecToken(BaseModel):
65
- actual: str = ""
66
- prev: str = ""
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
67
 
 
68
  class User(BaseModel):
69
  name: str
70
- gptTokens: dict = {}
71
  created: datetime = datetime.now(tz)
72
  approved: datetime | None = None
73
  description: str = ""
@@ -75,19 +98,35 @@ class User(BaseModel):
75
  gid: str
76
  role: str = "on hold"
77
  configs: Configs = Configs()
78
- viewToken: SecToken = SecToken()
79
- apiToken: SecToken = SecToken()
80
 
81
  @classmethod
82
  def find(cls, gid: str):
83
- found = user_table.find_one({"gid":gid})
84
  if found:
85
  return cls(**found)
86
  return None
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
87
 
88
  @classmethod
89
  def find_from_header(cls, request: Request):
90
- return cls.find_from_token(request, "api")
 
 
91
 
92
  @classmethod
93
  def find_from_cookie(cls, request: Request):
@@ -96,49 +135,35 @@ class User(BaseModel):
96
  @classmethod
97
  def find_from_token(cls, request: Request, usage: str):
98
  data = None
99
- token_type = None
100
  if usage=="view":
101
  data = security.token_from_cookie(request)
102
- token_type = "viewToken"
103
  else:
104
  data = security.token_from_headers(request)
105
- token_type = "apiToken"
106
-
107
- if data.pop("usage") != usage:
108
- log_module.logger.error(f"Bad usage - Invalid token: for usage {usage}")
109
- return security.raise_401()
110
 
111
- token_string = data.pop("token_string", "")
112
 
113
- user = user_table.find_one({"gid":data["gid"], f"{token_type}.actual":token_string})
114
- if not user:
 
 
115
  security.raise_307()
116
- return cls(**user)
 
 
117
 
118
 
119
- @classmethod
120
- def find_or_create(cls, data: dict):
121
- found = cls.find(data["gid"])
122
- if found:
123
- return found
124
- user = User(**data)
125
- user_table.insert_one(user.model_dump())
126
- log_module.logger.info(f"User created: {user.gid}")
127
- return user
128
 
129
  def create_token(self, usage: str):
130
- token = security.create_jwt_token({"gid": self.gid, "usage":usage}, usage)
131
  if usage=="view":
132
- self.viewToken.prev = self.viewToken.actual
133
- self.viewToken.actual = token
134
  else:
135
- self.apiToken.prev = self.apiToken.actual
136
- self.apiToken.actual = token
137
  return token
138
 
139
  def update_description(self, message):
140
  log_module.logger.info(f"Description Updated: {self.gid}")
141
- user_table.update_one(
142
  {"gid":self.gid},
143
  {"$set": { "description": message}}
144
  )
@@ -153,23 +178,19 @@ class User(BaseModel):
153
  count_tokens = message.tokensOutput+message.tokensPrompt
154
  now = datetime.now()
155
 
156
- if str(now.year) not in self.gptTokens:
157
- self.gptTokens[str(now.year)] = {}
158
 
159
- if str(now.month) not in self.gptTokens[str(now.year)]:
160
- self.gptTokens[str(now.year)][str(now.month)] = {}
161
 
162
- if str(now.day) not in self.gptTokens[str(now.year)][str(now.month)] :
163
- self.gptTokens[str(now.year)][str(now.month)][str(now.day)] = 0
164
 
165
- self.gptTokens[str(now.year)][str(now.month)][str(now.day)] += count_tokens
166
 
167
- user_table.update_one({"gid": self.gid}, {"$set": self.model_dump()})
 
 
 
168
 
169
- class Session:
170
- user: str
171
- m
172
- guid: str
173
- created: datetime = datetime.now(tz)
174
- updated: datetime
175
- expire: datetime
 
2
  from pymongo.mongo_client import MongoClient
3
  from pymongo.server_api import ServerApi
4
  from fastapi import Request
5
+ from . import log_module, security, settings
6
  from datetime import timezone, datetime, timedelta
7
+ from pydantic import BaseModel, Field
8
  from typing import List, Dict
9
  import tiktoken
10
+ import uuid
11
+ from typing import Annotated
12
 
13
 
14
+ client = MongoClient(settings.DB_URI, server_api=ServerApi('1'))
15
+ class __DB:
16
+ user = client.ChatDB.users
17
+ sess = client.ChatDB.sessions
18
+ DB = __DB()
 
 
 
19
 
20
  tz = timezone(timedelta(hours=-4))
21
+ encoding = tiktoken.encoding_for_model(settings.GPT_MODEL)
22
 
23
  def count_tokens_on_message(args):
24
  token_count = 0
 
60
  def new_msg(self):
61
  return Message(role="", content="")
62
 
63
+ class Session(BaseModel):
64
+ gid: str
65
+ guid: str = str(uuid.uuid4())
66
+ created: datetime = datetime.now(tz)
67
+ updated: datetime = datetime.now(tz)
68
+ expire: datetime = datetime.now(tz)+timedelta(days=7)
69
+
70
+ @classmethod
71
+ def find(cls, gid: str, guid: str):
72
+ sess = DB.sess.find_one({"gid": gid, "guid": guid})
73
+ if sess.expire < datetime.now(tz):
74
+ DB.sess.find_one_and_delete({"gid": gid, "guid": guid})
75
+ return False
76
+
77
+ sess.update = datetime.now(tz)
78
+ sess.expire = datetime.now(tz)+timedelta(days=7)
79
+
80
+ DB.sess.update_one({"gid": gid, "guid": guid}, {"$set": sess.model_dump()})
81
+
82
+ return guid
83
+
84
+ @classmethod
85
+ def create(cls, gid: str):
86
+ temp = cls(gid=gid)
87
+ DB.sess.insert_one(temp.model_dump())
88
+ return temp
89
 
90
+
91
  class User(BaseModel):
92
  name: str
93
+ tokens: dict = {}
94
  created: datetime = datetime.now(tz)
95
  approved: datetime | None = None
96
  description: str = ""
 
98
  gid: str
99
  role: str = "on hold"
100
  configs: Configs = Configs()
101
+ session: Session | None = None
 
102
 
103
  @classmethod
104
  def find(cls, gid: str):
105
+ found = DB.user.find_one({"gid":gid})
106
  if found:
107
  return cls(**found)
108
  return None
109
+
110
+ @classmethod
111
+ def find_or_create(cls, data: dict):
112
+ sess = Session.create(data["gid"])
113
+ found = cls.find(data["gid"])
114
+ if found:
115
+ found.session = sess
116
+ return found
117
+ user = User(**data)
118
+ user.session = sess
119
+
120
+ DB.user.insert_one(user.model_dump(exclude={"session"}))
121
+ log_module.logger.info(f"User created: {user.gid}")
122
+ return user
123
+
124
 
125
  @classmethod
126
  def find_from_header(cls, request: Request):
127
+ temp = cls.find_from_token(request, "api")
128
+
129
+ return temp
130
 
131
  @classmethod
132
  def find_from_cookie(cls, request: Request):
 
135
  @classmethod
136
  def find_from_token(cls, request: Request, usage: str):
137
  data = None
 
138
  if usage=="view":
139
  data = security.token_from_cookie(request)
 
140
  else:
141
  data = security.token_from_headers(request)
 
 
 
 
 
142
 
143
+ user = DB.user.find_one({"gid":data["gid"]})
144
 
145
+ if user:
146
+ sess = Session.find(user.gid, data["guid"])
147
+
148
+ if not user or not sess:
149
  security.raise_307()
150
+ user = cls(**user)
151
+ user.session = sess
152
+ return user
153
 
154
 
 
 
 
 
 
 
 
 
 
155
 
156
  def create_token(self, usage: str):
157
+ token = security.create_jwt_token({"gid": self.gid, "usage":usage, "guid": self.session.guid}, usage)
158
  if usage=="view":
159
+ pass
 
160
  else:
161
+ pass
 
162
  return token
163
 
164
  def update_description(self, message):
165
  log_module.logger.info(f"Description Updated: {self.gid}")
166
+ DB.user.update_one(
167
  {"gid":self.gid},
168
  {"$set": { "description": message}}
169
  )
 
178
  count_tokens = message.tokensOutput+message.tokensPrompt
179
  now = datetime.now()
180
 
181
+ if str(now.year) not in self.tokens:
182
+ self.tokens[str(now.year)] = {}
183
 
184
+ if str(now.month) not in self.tokens[str(now.year)]:
185
+ self.tokens[str(now.year)][str(now.month)] = {}
186
 
187
+ if str(now.day) not in self.tokens[str(now.year)][str(now.month)] :
188
+ self.tokens[str(now.year)][str(now.month)][str(now.day)] = 0
189
 
190
+ self.tokens[str(now.year)][str(now.month)][str(now.day)] += count_tokens
191
 
192
+ DB.user.update_one({"gid": self.gid}, {"$set": self.model_dump(exclude={"guid", "session"})})
193
+
194
+
195
+
196
 
 
 
 
 
 
 
 
modules/oauth.py CHANGED
@@ -1,16 +1,12 @@
1
  import requests, os
2
-
3
-
4
- GOOGLE_CLIENT_ID = os.environ.get("GOOGLE_CLIENT_ID", None)
5
- GOOGLE_CLIENT_SECRET = os.environ.get("GOOGLE_CLIENT_SECRET", None)
6
- OAUTH_REDIRECT = os.environ.get("OAUTH_REDIRECT", None)
7
 
8
  def validate_redirect(params):
9
  data = {
10
  'code': params["code"],
11
- 'redirect_uri': OAUTH_REDIRECT,
12
- 'client_id': GOOGLE_CLIENT_ID,
13
- 'client_secret': GOOGLE_CLIENT_SECRET,
14
  'scope': params["scope"],
15
  'grant_type': 'authorization_code'
16
  }
@@ -26,7 +22,7 @@ def validate_redirect(params):
26
  print(e)
27
  print(google_auth_rq.content)
28
  return str(e)+" "+google_auth_rq.content
29
- google_userinfo_rq = requests.get("https://www.googleapis.com/oauth2/v2/userinfo", headers=headers, timeout=5)
30
  ret = google_userinfo_rq.json()
31
  ret["gid"] = ret.get("id","")
32
  return ret
 
1
  import requests, os
2
+ from . import settings
 
 
 
 
3
 
4
  def validate_redirect(params):
5
  data = {
6
  'code': params["code"],
7
+ 'redirect_uri': settings.OAUTH_REDIRECT,
8
+ 'client_id': settings.GOOGLE_CLIENT_ID,
9
+ 'client_secret': settings.GOOGLE_CLIENT_SECRET,
10
  'scope': params["scope"],
11
  'grant_type': 'authorization_code'
12
  }
 
22
  print(e)
23
  print(google_auth_rq.content)
24
  return str(e)+" "+google_auth_rq.content
25
+ google_userinfo_rq = requests.get("https://www.googleapis.com/oauth2/v2/userinfo", headers=headers, timeout=30)
26
  ret = google_userinfo_rq.json()
27
  ret["gid"] = ret.get("id","")
28
  return ret
modules/security.py CHANGED
@@ -3,37 +3,34 @@ from hashlib import sha256
3
  from fastapi import HTTPException, status, Request
4
  from fastapi.security import HTTPBasicCredentials
5
  from fastapi.responses import RedirectResponse
6
- from . import log_module
7
- from datetime import datetime, timedelta
8
 
9
 
10
- users = json.loads(str(os.getenv("USER_KEYS")).replace("\n", ""))
11
- for key in users:
12
  if key == "master": continue
13
- password = key+users[key]+users["master"]
14
- users[key] = sha256(password.encode('UTF-8')).hexdigest()
 
15
 
16
- JWT_SECRET = users["master"]
17
- JWT_ALGORITHM = "HS256"
18
- JWT_EXPIRATION_TIME_MINUTES_API = 30
19
- JWT_EXPIRATION_TIME_MINUTES_VIEW = 7*24*60
20
 
21
 
22
  def create_jwt_token(data, usage):
23
  to_encode = data
24
 
25
  if usage == "api":
26
- expire = datetime.utcnow() + timedelta(minutes=JWT_EXPIRATION_TIME_MINUTES_API)
27
  elif usage == "view":
28
- expire = datetime.utcnow() + timedelta(minutes=JWT_EXPIRATION_TIME_MINUTES_VIEW)
29
 
30
  to_encode.update({"exp": expire})
31
- encoded_jwt = jwt.encode(to_encode, JWT_SECRET, algorithm=JWT_ALGORITHM)
32
  return encoded_jwt
33
 
34
  def validate_jwt_token(token: str, usage: str = "api"):
35
  try:
36
- payload = jwt.decode(token, JWT_SECRET, algorithms=[JWT_ALGORITHM])
37
  return payload
38
  except Exception as e:
39
  log_module.logger.error(repr(e) + " - Invalid token: " + str(token))
@@ -43,12 +40,12 @@ def validate_jwt_token(token: str, usage: str = "api"):
43
 
44
  def token_from_cookie(request:Request):
45
  if token := request.cookies.get('token', ""):
46
- return validate_jwt_token(token, "view") | {"token_string": token}
47
  return raise_307()
48
 
49
  def token_from_headers(request:Request):
50
  if (bearer := request.headers.get("Autorization", " ").split(" ",1)) and bearer[0] == "Bearer":
51
- return validate_jwt_token(bearer[1]) | {"token_string": bearer[1]}
52
  return raise_401()
53
 
54
 
 
3
  from fastapi import HTTPException, status, Request
4
  from fastapi.security import HTTPBasicCredentials
5
  from fastapi.responses import RedirectResponse
6
+ from . import log_module, settings
7
+ from datetime import datetime, timedelta
8
 
9
 
10
+
11
+ for key in settings.USERS:
12
  if key == "master": continue
13
+ password = key+settings.USERS[key]+settings.USERS["master"]
14
+ settings.USERS[key] = sha256(password.encode('UTF-8')).hexdigest()
15
+
16
 
 
 
 
 
17
 
18
 
19
  def create_jwt_token(data, usage):
20
  to_encode = data
21
 
22
  if usage == "api":
23
+ expire = datetime.utcnow() + timedelta(minutes=settings.JWT_EXPIRATION_TIME_MINUTES_API)
24
  elif usage == "view":
25
+ expire = datetime.utcnow() + timedelta(minutes=settings.JWT_EXPIRATION_TIME_MINUTES_VIEW)
26
 
27
  to_encode.update({"exp": expire})
28
+ encoded_jwt = jwt.encode(to_encode, settings.JWT_SECRET, algorithm=settings.JWT_ALGORITHM)
29
  return encoded_jwt
30
 
31
  def validate_jwt_token(token: str, usage: str = "api"):
32
  try:
33
+ payload = jwt.decode(token, settings.JWT_SECRET, algorithms=[settings.JWT_ALGORITHM])
34
  return payload
35
  except Exception as e:
36
  log_module.logger.error(repr(e) + " - Invalid token: " + str(token))
 
40
 
41
  def token_from_cookie(request:Request):
42
  if token := request.cookies.get('token', ""):
43
+ return validate_jwt_token(token, "view")
44
  return raise_307()
45
 
46
  def token_from_headers(request:Request):
47
  if (bearer := request.headers.get("Autorization", " ").split(" ",1)) and bearer[0] == "Bearer":
48
+ return validate_jwt_token(bearer[1])
49
  return raise_401()
50
 
51
 
modules/settings.py ADDED
@@ -0,0 +1,31 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import os, json
2
+
3
+ from datetime import timezone, datetime, timedelta
4
+ from pymongo.mongo_client import MongoClient
5
+ from pymongo.server_api import ServerApi
6
+
7
+
8
+ TZ = timezone(timedelta(hours=-4))
9
+
10
+ GPT_MODEL = "gpt-3.5-turbo-1106"
11
+
12
+ MONGO_URL = os.environ.get("MONGO_URL", None)
13
+ MONGO_PWD = os.environ.get("MONGO_PWD", None)
14
+ MONGO_USR = os.environ.get("MONGO_USR", None)
15
+ #DB_URI = f"mongodb+srv://{MONGO_USR}:{MONGO_PWD}@{MONGO_URL}/?retryWrites=true&w=majority"
16
+ DB_URI = "mongodb://127.0.0.1:27017"
17
+
18
+ OPENAI_API_KEY=os.environ.get('OPENAI_API_KEY')
19
+
20
+
21
+ USERS = json.loads(str(os.getenv("USER_KEYS")).replace("\n", ""))
22
+
23
+ JWT_SECRET = USERS["master"]
24
+ JWT_ALGORITHM = "HS256"
25
+ JWT_EXPIRATION_TIME_MINUTES_API = 30
26
+ JWT_EXPIRATION_TIME_MINUTES_VIEW = 7*24*60
27
+
28
+
29
+ GOOGLE_CLIENT_ID = os.environ.get("GOOGLE_CLIENT_ID")
30
+ GOOGLE_CLIENT_SECRET = os.environ.get("GOOGLE_CLIENT_SECRET")
31
+ OAUTH_REDIRECT = os.environ.get("OAUTH_REDIRECT")
static/js/fingerprint.js DELETED
@@ -1,101 +0,0 @@
1
- var codecs = ['application/ogg',
2
- 'application/ogg; codecs=bogus',
3
- 'application/mp4',
4
- 'application/mp4; codecs=bogus',
5
- 'application/octet-stream',
6
- 'application/octet-stream; codecs=bogus',
7
- 'audio/3gpp',
8
- 'audio/3gpp2',
9
- 'audio/aac',
10
- 'audio/x-aac',
11
- 'audio/aiff',
12
- 'audio/x-aiff',
13
- 'audio/ac3',
14
- 'audio/x-ac3',
15
- 'audio/basic',
16
- 'audio/flac',
17
- 'audio/x-flac',
18
- 'audio/mid',
19
- 'audio/midi',
20
- 'audio/x-midi',
21
- 'audio/mpeg',
22
- 'audio/x-mpeg',
23
- 'audio/mpegurl',
24
- 'audio/x-mpegurl',
25
- 'audio/mp4',
26
- 'audio/mp4; codecs=bogus',
27
- 'audio/ogg',
28
- 'audio/ogg; codecs=bogus',
29
- 'audio/wav',
30
- 'audio/wav; codecs=0',
31
- 'audio/wav; codecs=1',
32
- 'audio/wav; codecs=2',
33
- 'audio/wave',
34
- 'audio/wave; codecs=0',
35
- 'audio/wave; codecs=1',
36
- 'audio/wave; codecs=2',
37
- 'audio/x-wav',
38
- 'audio/x-wav; codecs=0',
39
- 'audio/x-wav; codecs=1',
40
- 'audio/x-wav; codecs=2',
41
- 'audio/x-pn-wav',
42
- 'audio/x-pn-wav; codecs=0',
43
- 'audio/x-pn-wav; codecs=1',
44
- 'audio/x-pn-wav; codecs=2',
45
- 'video/3gpp',
46
- 'video/3gpp2',
47
- 'video/avi',
48
- 'video/mpeg',
49
- 'video/x-mpeg',
50
- 'video/mp4',
51
- 'video/mp4; codecs=bogus',
52
- 'video/msvideo',
53
- 'video/x-msvideo',
54
- 'video/quicktime',
55
- 'video/ogg',
56
- 'video/ogg; codecs=bogus',
57
- 'video/mp4; codecs="avc1.42E01E, mp4a.40.2"',
58
- 'video/mp4; codecs="avc1.58A01E, mp4a.40.2"',
59
- 'video/mp4; codecs="avc1.4D401E, mp4a.40.2"',
60
- 'video/mp4; codecs="avc1.64001E, mp4a.40.2"',
61
- 'video/mp4; codecs="mp4v.20.8, mp4a.40.2"',
62
- 'video/mp4; codecs="mp4v.20.240, mp4a.40.2"',
63
- 'video/mp4; codecs="avc1.64001E, mp4a.40.2"',
64
- 'video/mp4; codecs="mp4v.20.8, mp4a.40.2"',
65
- 'video/mp4; codecs=hev1',
66
- 'video/mp4; codecs=hev1.1.6.L93.B0',
67
- 'video/mp4; codecs=hvc1',
68
- 'video/mp4; codecs=hvc1.1.6.L93.B0',
69
- 'video/mp4; codecs=av01',
70
- 'video/mp4; codecs=av01.0.04M.08',
71
- 'video/mp4; codecs="av01.0.04M.08, mp4a.40.2"',
72
- 'video/mp4; codecs="av01.0.04M.08, opus"',
73
- 'audio/mp4; codecs=mp4a.40.2',
74
- 'audio/mp4; codecs=mp4a.40.02',
75
- 'audio/mp4; codecs=mp4a.40.5',
76
- 'audio/mp4; codecs=mp4a.40.05',
77
- 'audio/mp4; codecs=mp4a.40.29',
78
- 'audio/mp4; codecs=mp4a.40.42',
79
- 'audio/mp4; codecs=opus',
80
- 'video/3gpp; codecs="mp4v.20.8, samr"',
81
- 'video/ogg; codecs="theora, vorbis"',
82
- 'video/ogg; codecs="theora, speex"',
83
- 'audio/ogg; codecs=vorbis',
84
- 'audio/ogg; codecs=speex',
85
- 'audio/ogg; codecs=flac',
86
- 'audio/ogg; codecs=opus',
87
- 'video/ogg; codecs="dirac, vorbis"',
88
- 'video/x-matroska; codecs="theora, vorbis"',
89
- 'audio/webm',
90
- 'audio/webm; codecs=vorbis',
91
- 'video/webm',
92
- 'video/webm; codecs=vorbis',
93
- 'video/webm; codecs=vp8',
94
- 'video/webm; codecs=vp8.0',
95
- 'video/webm; codecs="vp8, vorbis"',
96
- 'video/webm; codecs=vp9',
97
- 'video/webm; codecs=vp9.0',
98
- 'video/webm; codecs=vp09',
99
- 'video/webm; codecs=vp09.00.10.08']
100
-
101
- window.navigator.userAgent
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
token_counter.py DELETED
@@ -1,17 +0,0 @@
1
- import tiktoken
2
- def count_tokens(messages, model="gpt-3.5-turbo-16k"):
3
- """Returns the number of tokens used by a list of messages."""
4
- try:
5
- encoding = tiktoken.encoding_for_model(model)
6
- except KeyError:
7
- encoding = tiktoken.get_encoding("cl100k_base")
8
-
9
- num_tokens = 0
10
- for message in messages:
11
- num_tokens += 4 # every message follows <im_start>{role/name}\n{content}<im_end>\n
12
- for key, value in message.items():
13
- num_tokens += len(encoding.encode(value))
14
- if key == "name": # if there's a name, the role is omitted
15
- num_tokens += -1 # role is always required and always 1 token
16
- num_tokens += 2 # every reply is primed with <im_start>assistant
17
- return num_tokens