Du kannst nicht mehr als 25 Themen auswählen Themen müssen mit entweder einem Buchstaben oder einer Ziffer beginnen. Sie können Bindestriche („-“) enthalten und bis zu 35 Zeichen lang sein.

db_models.py 25KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764
  1. #
  2. # Copyright 2024 The InfiniFlow Authors. All Rights Reserved.
  3. #
  4. # Licensed under the Apache License, Version 2.0 (the "License");
  5. # you may not use this file except in compliance with the License.
  6. # You may obtain a copy of the License at
  7. #
  8. # http://www.apache.org/licenses/LICENSE-2.0
  9. #
  10. # Unless required by applicable law or agreed to in writing, software
  11. # distributed under the License is distributed on an "AS IS" BASIS,
  12. # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. # See the License for the specific language governing permissions and
  14. # limitations under the License.
  15. #
  16. import inspect
  17. import os
  18. import sys
  19. import typing
  20. import operator
  21. from functools import wraps
  22. from itsdangerous.url_safe import URLSafeTimedSerializer as Serializer
  23. from flask_login import UserMixin
  24. from peewee import (
  25. BigAutoField, BigIntegerField, BooleanField, CharField,
  26. CompositeKey, Insert, IntegerField, TextField, FloatField, DateTimeField,
  27. Field, Model, Metadata
  28. )
  29. from playhouse.pool import PooledMySQLDatabase
  30. from api.db import SerializedType, ParserType
  31. from api.settings import DATABASE, stat_logger, SECRET_KEY
  32. from api.utils.log_utils import getLogger
  33. from api import utils
  34. LOGGER = getLogger()
  35. def singleton(cls, *args, **kw):
  36. instances = {}
  37. def _singleton():
  38. key = str(cls) + str(os.getpid())
  39. if key not in instances:
  40. instances[key] = cls(*args, **kw)
  41. return instances[key]
  42. return _singleton
  43. CONTINUOUS_FIELD_TYPE = {IntegerField, FloatField, DateTimeField}
  44. AUTO_DATE_TIMESTAMP_FIELD_PREFIX = {
  45. "create",
  46. "start",
  47. "end",
  48. "update",
  49. "read_access",
  50. "write_access"}
  51. class LongTextField(TextField):
  52. field_type = 'LONGTEXT'
  53. class JSONField(LongTextField):
  54. default_value = {}
  55. def __init__(self, object_hook=None, object_pairs_hook=None, **kwargs):
  56. self._object_hook = object_hook
  57. self._object_pairs_hook = object_pairs_hook
  58. super().__init__(**kwargs)
  59. def db_value(self, value):
  60. if value is None:
  61. value = self.default_value
  62. return utils.json_dumps(value)
  63. def python_value(self, value):
  64. if not value:
  65. return self.default_value
  66. return utils.json_loads(
  67. value, object_hook=self._object_hook, object_pairs_hook=self._object_pairs_hook)
  68. class ListField(JSONField):
  69. default_value = []
  70. class SerializedField(LongTextField):
  71. def __init__(self, serialized_type=SerializedType.PICKLE,
  72. object_hook=None, object_pairs_hook=None, **kwargs):
  73. self._serialized_type = serialized_type
  74. self._object_hook = object_hook
  75. self._object_pairs_hook = object_pairs_hook
  76. super().__init__(**kwargs)
  77. def db_value(self, value):
  78. if self._serialized_type == SerializedType.PICKLE:
  79. return utils.serialize_b64(value, to_str=True)
  80. elif self._serialized_type == SerializedType.JSON:
  81. if value is None:
  82. return None
  83. return utils.json_dumps(value, with_type=True)
  84. else:
  85. raise ValueError(
  86. f"the serialized type {self._serialized_type} is not supported")
  87. def python_value(self, value):
  88. if self._serialized_type == SerializedType.PICKLE:
  89. return utils.deserialize_b64(value)
  90. elif self._serialized_type == SerializedType.JSON:
  91. if value is None:
  92. return {}
  93. return utils.json_loads(
  94. value, object_hook=self._object_hook, object_pairs_hook=self._object_pairs_hook)
  95. else:
  96. raise ValueError(
  97. f"the serialized type {self._serialized_type} is not supported")
  98. def is_continuous_field(cls: typing.Type) -> bool:
  99. if cls in CONTINUOUS_FIELD_TYPE:
  100. return True
  101. for p in cls.__bases__:
  102. if p in CONTINUOUS_FIELD_TYPE:
  103. return True
  104. elif p != Field and p != object:
  105. if is_continuous_field(p):
  106. return True
  107. else:
  108. return False
  109. def auto_date_timestamp_field():
  110. return {f"{f}_time" for f in AUTO_DATE_TIMESTAMP_FIELD_PREFIX}
  111. def auto_date_timestamp_db_field():
  112. return {f"f_{f}_time" for f in AUTO_DATE_TIMESTAMP_FIELD_PREFIX}
  113. def remove_field_name_prefix(field_name):
  114. return field_name[2:] if field_name.startswith('f_') else field_name
  115. class BaseModel(Model):
  116. create_time = BigIntegerField(null=True)
  117. create_date = DateTimeField(null=True)
  118. update_time = BigIntegerField(null=True)
  119. update_date = DateTimeField(null=True)
  120. def to_json(self):
  121. # This function is obsolete
  122. return self.to_dict()
  123. def to_dict(self):
  124. return self.__dict__['__data__']
  125. def to_human_model_dict(self, only_primary_with: list = None):
  126. model_dict = self.__dict__['__data__']
  127. if not only_primary_with:
  128. return {remove_field_name_prefix(
  129. k): v for k, v in model_dict.items()}
  130. human_model_dict = {}
  131. for k in self._meta.primary_key.field_names:
  132. human_model_dict[remove_field_name_prefix(k)] = model_dict[k]
  133. for k in only_primary_with:
  134. human_model_dict[k] = model_dict[f'f_{k}']
  135. return human_model_dict
  136. @property
  137. def meta(self) -> Metadata:
  138. return self._meta
  139. @classmethod
  140. def get_primary_keys_name(cls):
  141. return cls._meta.primary_key.field_names if isinstance(cls._meta.primary_key, CompositeKey) else [
  142. cls._meta.primary_key.name]
  143. @classmethod
  144. def getter_by(cls, attr):
  145. return operator.attrgetter(attr)(cls)
  146. @classmethod
  147. def query(cls, reverse=None, order_by=None, **kwargs):
  148. filters = []
  149. for f_n, f_v in kwargs.items():
  150. attr_name = '%s' % f_n
  151. if not hasattr(cls, attr_name) or f_v is None:
  152. continue
  153. if type(f_v) in {list, set}:
  154. f_v = list(f_v)
  155. if is_continuous_field(type(getattr(cls, attr_name))):
  156. if len(f_v) == 2:
  157. for i, v in enumerate(f_v):
  158. if isinstance(
  159. v, str) and f_n in auto_date_timestamp_field():
  160. # time type: %Y-%m-%d %H:%M:%S
  161. f_v[i] = utils.date_string_to_timestamp(v)
  162. lt_value = f_v[0]
  163. gt_value = f_v[1]
  164. if lt_value is not None and gt_value is not None:
  165. filters.append(
  166. cls.getter_by(attr_name).between(
  167. lt_value, gt_value))
  168. elif lt_value is not None:
  169. filters.append(
  170. operator.attrgetter(attr_name)(cls) >= lt_value)
  171. elif gt_value is not None:
  172. filters.append(
  173. operator.attrgetter(attr_name)(cls) <= gt_value)
  174. else:
  175. filters.append(operator.attrgetter(attr_name)(cls) << f_v)
  176. else:
  177. filters.append(operator.attrgetter(attr_name)(cls) == f_v)
  178. if filters:
  179. query_records = cls.select().where(*filters)
  180. if reverse is not None:
  181. if not order_by or not hasattr(cls, f"{order_by}"):
  182. order_by = "create_time"
  183. if reverse is True:
  184. query_records = query_records.order_by(
  185. cls.getter_by(f"{order_by}").desc())
  186. elif reverse is False:
  187. query_records = query_records.order_by(
  188. cls.getter_by(f"{order_by}").asc())
  189. return [query_record for query_record in query_records]
  190. else:
  191. return []
  192. @classmethod
  193. def insert(cls, __data=None, **insert):
  194. if isinstance(__data, dict) and __data:
  195. __data[cls._meta.combined["create_time"]
  196. ] = utils.current_timestamp()
  197. if insert:
  198. insert["create_time"] = utils.current_timestamp()
  199. return super().insert(__data, **insert)
  200. # update and insert will call this method
  201. @classmethod
  202. def _normalize_data(cls, data, kwargs):
  203. normalized = super()._normalize_data(data, kwargs)
  204. if not normalized:
  205. return {}
  206. normalized[cls._meta.combined["update_time"]
  207. ] = utils.current_timestamp()
  208. for f_n in AUTO_DATE_TIMESTAMP_FIELD_PREFIX:
  209. if {f"{f_n}_time", f"{f_n}_date"}.issubset(cls._meta.combined.keys()) and \
  210. cls._meta.combined[f"{f_n}_time"] in normalized and \
  211. normalized[cls._meta.combined[f"{f_n}_time"]] is not None:
  212. normalized[cls._meta.combined[f"{f_n}_date"]] = utils.timestamp_to_date(
  213. normalized[cls._meta.combined[f"{f_n}_time"]])
  214. return normalized
  215. class JsonSerializedField(SerializedField):
  216. def __init__(self, object_hook=utils.from_dict_hook,
  217. object_pairs_hook=None, **kwargs):
  218. super(JsonSerializedField, self).__init__(serialized_type=SerializedType.JSON, object_hook=object_hook,
  219. object_pairs_hook=object_pairs_hook, **kwargs)
  220. @singleton
  221. class BaseDataBase:
  222. def __init__(self):
  223. database_config = DATABASE.copy()
  224. db_name = database_config.pop("name")
  225. self.database_connection = PooledMySQLDatabase(
  226. db_name, **database_config)
  227. stat_logger.info('init mysql database on cluster mode successfully')
  228. class DatabaseLock:
  229. def __init__(self, lock_name, timeout=10, db=None):
  230. self.lock_name = lock_name
  231. self.timeout = int(timeout)
  232. self.db = db if db else DB
  233. def lock(self):
  234. # SQL parameters only support %s format placeholders
  235. cursor = self.db.execute_sql(
  236. "SELECT GET_LOCK(%s, %s)", (self.lock_name, self.timeout))
  237. ret = cursor.fetchone()
  238. if ret[0] == 0:
  239. raise Exception(f'acquire mysql lock {self.lock_name} timeout')
  240. elif ret[0] == 1:
  241. return True
  242. else:
  243. raise Exception(f'failed to acquire lock {self.lock_name}')
  244. def unlock(self):
  245. cursor = self.db.execute_sql(
  246. "SELECT RELEASE_LOCK(%s)", (self.lock_name,))
  247. ret = cursor.fetchone()
  248. if ret[0] == 0:
  249. raise Exception(
  250. f'mysql lock {self.lock_name} was not established by this thread')
  251. elif ret[0] == 1:
  252. return True
  253. else:
  254. raise Exception(f'mysql lock {self.lock_name} does not exist')
  255. def __enter__(self):
  256. if isinstance(self.db, PooledMySQLDatabase):
  257. self.lock()
  258. return self
  259. def __exit__(self, exc_type, exc_val, exc_tb):
  260. if isinstance(self.db, PooledMySQLDatabase):
  261. self.unlock()
  262. def __call__(self, func):
  263. @wraps(func)
  264. def magic(*args, **kwargs):
  265. with self:
  266. return func(*args, **kwargs)
  267. return magic
  268. DB = BaseDataBase().database_connection
  269. DB.lock = DatabaseLock
  270. def close_connection():
  271. try:
  272. if DB:
  273. DB.close()
  274. except Exception as e:
  275. LOGGER.exception(e)
  276. class DataBaseModel(BaseModel):
  277. class Meta:
  278. database = DB
  279. @DB.connection_context()
  280. def init_database_tables():
  281. members = inspect.getmembers(sys.modules[__name__], inspect.isclass)
  282. table_objs = []
  283. create_failed_list = []
  284. for name, obj in members:
  285. if obj != DataBaseModel and issubclass(obj, DataBaseModel):
  286. table_objs.append(obj)
  287. LOGGER.info(f"start create table {obj.__name__}")
  288. try:
  289. obj.create_table()
  290. LOGGER.info(f"create table success: {obj.__name__}")
  291. except Exception as e:
  292. LOGGER.exception(e)
  293. create_failed_list.append(obj.__name__)
  294. if create_failed_list:
  295. LOGGER.info(f"create tables failed: {create_failed_list}")
  296. raise Exception(f"create tables failed: {create_failed_list}")
  297. def fill_db_model_object(model_object, human_model_dict):
  298. for k, v in human_model_dict.items():
  299. attr_name = '%s' % k
  300. if hasattr(model_object.__class__, attr_name):
  301. setattr(model_object, attr_name, v)
  302. return model_object
  303. class User(DataBaseModel, UserMixin):
  304. id = CharField(max_length=32, primary_key=True)
  305. access_token = CharField(max_length=255, null=True)
  306. nickname = CharField(max_length=100, null=False, help_text="nicky name")
  307. password = CharField(max_length=255, null=True, help_text="password")
  308. email = CharField(
  309. max_length=255,
  310. null=False,
  311. help_text="email",
  312. index=True)
  313. avatar = TextField(null=True, help_text="avatar base64 string")
  314. language = CharField(
  315. max_length=32,
  316. null=True,
  317. help_text="English|Chinese",
  318. default="English")
  319. color_schema = CharField(
  320. max_length=32,
  321. null=True,
  322. help_text="Bright|Dark",
  323. default="Bright")
  324. timezone = CharField(
  325. max_length=64,
  326. null=True,
  327. help_text="Timezone",
  328. default="UTC+8\tAsia/Shanghai")
  329. last_login_time = DateTimeField(null=True)
  330. is_authenticated = CharField(max_length=1, null=False, default="1")
  331. is_active = CharField(max_length=1, null=False, default="1")
  332. is_anonymous = CharField(max_length=1, null=False, default="0")
  333. login_channel = CharField(null=True, help_text="from which user login")
  334. status = CharField(
  335. max_length=1,
  336. null=True,
  337. help_text="is it validate(0: wasted,1: validate)",
  338. default="1")
  339. is_superuser = BooleanField(null=True, help_text="is root", default=False)
  340. def __str__(self):
  341. return self.email
  342. def get_id(self):
  343. jwt = Serializer(secret_key=SECRET_KEY)
  344. return jwt.dumps(str(self.access_token))
  345. class Meta:
  346. db_table = "user"
  347. class Tenant(DataBaseModel):
  348. id = CharField(max_length=32, primary_key=True)
  349. name = CharField(max_length=100, null=True, help_text="Tenant name")
  350. public_key = CharField(max_length=255, null=True)
  351. llm_id = CharField(max_length=128, null=False, help_text="default llm ID")
  352. embd_id = CharField(
  353. max_length=128,
  354. null=False,
  355. help_text="default embedding model ID")
  356. asr_id = CharField(
  357. max_length=128,
  358. null=False,
  359. help_text="default ASR model ID")
  360. img2txt_id = CharField(
  361. max_length=128,
  362. null=False,
  363. help_text="default image to text model ID")
  364. parser_ids = CharField(
  365. max_length=256,
  366. null=False,
  367. help_text="document processors")
  368. credit = IntegerField(default=512)
  369. status = CharField(
  370. max_length=1,
  371. null=True,
  372. help_text="is it validate(0: wasted,1: validate)",
  373. default="1")
  374. class Meta:
  375. db_table = "tenant"
  376. class UserTenant(DataBaseModel):
  377. id = CharField(max_length=32, primary_key=True)
  378. user_id = CharField(max_length=32, null=False)
  379. tenant_id = CharField(max_length=32, null=False)
  380. role = CharField(max_length=32, null=False, help_text="UserTenantRole")
  381. invited_by = CharField(max_length=32, null=False)
  382. status = CharField(
  383. max_length=1,
  384. null=True,
  385. help_text="is it validate(0: wasted,1: validate)",
  386. default="1")
  387. class Meta:
  388. db_table = "user_tenant"
  389. class InvitationCode(DataBaseModel):
  390. id = CharField(max_length=32, primary_key=True)
  391. code = CharField(max_length=32, null=False)
  392. visit_time = DateTimeField(null=True)
  393. user_id = CharField(max_length=32, null=True)
  394. tenant_id = CharField(max_length=32, null=True)
  395. status = CharField(
  396. max_length=1,
  397. null=True,
  398. help_text="is it validate(0: wasted,1: validate)",
  399. default="1")
  400. class Meta:
  401. db_table = "invitation_code"
  402. class LLMFactories(DataBaseModel):
  403. name = CharField(
  404. max_length=128,
  405. null=False,
  406. help_text="LLM factory name",
  407. primary_key=True)
  408. logo = TextField(null=True, help_text="llm logo base64")
  409. tags = CharField(
  410. max_length=255,
  411. null=False,
  412. help_text="LLM, Text Embedding, Image2Text, ASR")
  413. status = CharField(
  414. max_length=1,
  415. null=True,
  416. help_text="is it validate(0: wasted,1: validate)",
  417. default="1")
  418. def __str__(self):
  419. return self.name
  420. class Meta:
  421. db_table = "llm_factories"
  422. class LLM(DataBaseModel):
  423. # LLMs dictionary
  424. llm_name = CharField(
  425. max_length=128,
  426. null=False,
  427. help_text="LLM name",
  428. index=True,
  429. primary_key=True)
  430. model_type = CharField(
  431. max_length=128,
  432. null=False,
  433. help_text="LLM, Text Embedding, Image2Text, ASR")
  434. fid = CharField(max_length=128, null=False, help_text="LLM factory id")
  435. max_tokens = IntegerField(default=0)
  436. tags = CharField(
  437. max_length=255,
  438. null=False,
  439. help_text="LLM, Text Embedding, Image2Text, Chat, 32k...")
  440. status = CharField(
  441. max_length=1,
  442. null=True,
  443. help_text="is it validate(0: wasted,1: validate)",
  444. default="1")
  445. def __str__(self):
  446. return self.llm_name
  447. class Meta:
  448. db_table = "llm"
  449. class TenantLLM(DataBaseModel):
  450. tenant_id = CharField(max_length=32, null=False)
  451. llm_factory = CharField(
  452. max_length=128,
  453. null=False,
  454. help_text="LLM factory name")
  455. model_type = CharField(
  456. max_length=128,
  457. null=True,
  458. help_text="LLM, Text Embedding, Image2Text, ASR")
  459. llm_name = CharField(
  460. max_length=128,
  461. null=True,
  462. help_text="LLM name",
  463. default="")
  464. api_key = CharField(max_length=255, null=True, help_text="API KEY")
  465. api_base = CharField(max_length=255, null=True, help_text="API Base")
  466. used_tokens = IntegerField(default=0)
  467. def __str__(self):
  468. return self.llm_name
  469. class Meta:
  470. db_table = "tenant_llm"
  471. primary_key = CompositeKey('tenant_id', 'llm_factory', 'llm_name')
  472. class Knowledgebase(DataBaseModel):
  473. id = CharField(max_length=32, primary_key=True)
  474. avatar = TextField(null=True, help_text="avatar base64 string")
  475. tenant_id = CharField(max_length=32, null=False)
  476. name = CharField(
  477. max_length=128,
  478. null=False,
  479. help_text="KB name",
  480. index=True)
  481. language = CharField(
  482. max_length=32,
  483. null=True,
  484. default="English",
  485. help_text="English|Chinese")
  486. description = TextField(null=True, help_text="KB description")
  487. embd_id = CharField(
  488. max_length=128,
  489. null=False,
  490. help_text="default embedding model ID")
  491. permission = CharField(
  492. max_length=16,
  493. null=False,
  494. help_text="me|team",
  495. default="me")
  496. created_by = CharField(max_length=32, null=False)
  497. doc_num = IntegerField(default=0)
  498. token_num = IntegerField(default=0)
  499. chunk_num = IntegerField(default=0)
  500. similarity_threshold = FloatField(default=0.2)
  501. vector_similarity_weight = FloatField(default=0.3)
  502. parser_id = CharField(
  503. max_length=32,
  504. null=False,
  505. help_text="default parser ID",
  506. default=ParserType.NAIVE.value)
  507. parser_config = JSONField(null=False, default={"pages": [[1, 1000000]]})
  508. status = CharField(
  509. max_length=1,
  510. null=True,
  511. help_text="is it validate(0: wasted,1: validate)",
  512. default="1")
  513. def __str__(self):
  514. return self.name
  515. class Meta:
  516. db_table = "knowledgebase"
  517. class Document(DataBaseModel):
  518. id = CharField(max_length=32, primary_key=True)
  519. thumbnail = TextField(null=True, help_text="thumbnail base64 string")
  520. kb_id = CharField(max_length=256, null=False, index=True)
  521. parser_id = CharField(
  522. max_length=32,
  523. null=False,
  524. help_text="default parser ID")
  525. parser_config = JSONField(null=False, default={"pages": [[1, 1000000]]})
  526. source_type = CharField(
  527. max_length=128,
  528. null=False,
  529. default="local",
  530. help_text="where dose this document come from")
  531. type = CharField(max_length=32, null=False, help_text="file extension")
  532. created_by = CharField(
  533. max_length=32,
  534. null=False,
  535. help_text="who created it")
  536. name = CharField(
  537. max_length=255,
  538. null=True,
  539. help_text="file name",
  540. index=True)
  541. location = CharField(
  542. max_length=255,
  543. null=True,
  544. help_text="where dose it store")
  545. size = IntegerField(default=0)
  546. token_num = IntegerField(default=0)
  547. chunk_num = IntegerField(default=0)
  548. progress = FloatField(default=0)
  549. progress_msg = TextField(
  550. null=True,
  551. help_text="process message",
  552. default="")
  553. process_begin_at = DateTimeField(null=True)
  554. process_duation = FloatField(default=0)
  555. run = CharField(
  556. max_length=1,
  557. null=True,
  558. help_text="start to run processing or cancel.(1: run it; 2: cancel)",
  559. default="0")
  560. status = CharField(
  561. max_length=1,
  562. null=True,
  563. help_text="is it validate(0: wasted,1: validate)",
  564. default="1")
  565. class Meta:
  566. db_table = "document"
  567. class Task(DataBaseModel):
  568. id = CharField(max_length=32, primary_key=True)
  569. doc_id = CharField(max_length=32, null=False, index=True)
  570. from_page = IntegerField(default=0)
  571. to_page = IntegerField(default=-1)
  572. begin_at = DateTimeField(null=True)
  573. process_duation = FloatField(default=0)
  574. progress = FloatField(default=0)
  575. progress_msg = TextField(
  576. null=True,
  577. help_text="process message",
  578. default="")
  579. class Dialog(DataBaseModel):
  580. id = CharField(max_length=32, primary_key=True)
  581. tenant_id = CharField(max_length=32, null=False)
  582. name = CharField(
  583. max_length=255,
  584. null=True,
  585. help_text="dialog application name")
  586. description = TextField(null=True, help_text="Dialog description")
  587. icon = TextField(null=True, help_text="icon base64 string")
  588. language = CharField(
  589. max_length=32,
  590. null=True,
  591. default="Chinese",
  592. help_text="English|Chinese")
  593. llm_id = CharField(max_length=32, null=False, help_text="default llm ID")
  594. llm_setting = JSONField(null=False, default={"temperature": 0.1, "top_p": 0.3, "frequency_penalty": 0.7,
  595. "presence_penalty": 0.4, "max_tokens": 215})
  596. prompt_type = CharField(
  597. max_length=16,
  598. null=False,
  599. default="simple",
  600. help_text="simple|advanced")
  601. prompt_config = JSONField(null=False, default={"system": "", "prologue": "您好,我是您的助手小樱,长得可爱又善良,can I help you?",
  602. "parameters": [], "empty_response": "Sorry! 知识库中未找到相关内容!"})
  603. similarity_threshold = FloatField(default=0.2)
  604. vector_similarity_weight = FloatField(default=0.3)
  605. top_n = IntegerField(default=6)
  606. do_refer = CharField(
  607. max_length=1,
  608. null=False,
  609. help_text="it needs to insert reference index into answer or not",
  610. default="1")
  611. kb_ids = JSONField(null=False, default=[])
  612. status = CharField(
  613. max_length=1,
  614. null=True,
  615. help_text="is it validate(0: wasted,1: validate)",
  616. default="1")
  617. class Meta:
  618. db_table = "dialog"
  619. class Conversation(DataBaseModel):
  620. id = CharField(max_length=32, primary_key=True)
  621. dialog_id = CharField(max_length=32, null=False, index=True)
  622. name = CharField(max_length=255, null=True, help_text="converastion name")
  623. message = JSONField(null=True)
  624. reference = JSONField(null=True, default=[])
  625. class Meta:
  626. db_table = "conversation"
  627. class APIToken(DataBaseModel):
  628. tenant_id = CharField(max_length=32, null=False)
  629. token = CharField(max_length=255, null=False)
  630. dialog_id = CharField(max_length=32, null=False, index=True)
  631. class Meta:
  632. db_table = "api_token"
  633. primary_key = CompositeKey('tenant_id', 'token')
  634. class API4Conversation(DataBaseModel):
  635. id = CharField(max_length=32, primary_key=True)
  636. dialog_id = CharField(max_length=32, null=False, index=True)
  637. user_id = CharField(max_length=255, null=False, help_text="user_id")
  638. message = JSONField(null=True)
  639. reference = JSONField(null=True, default=[])
  640. tokens = IntegerField(default=0)
  641. duration = FloatField(default=0)
  642. round = IntegerField(default=0)
  643. thumb_up = IntegerField(default=0)
  644. class Meta:
  645. db_table = "api_4_conversation"