aistv 1.3.6__tar.gz → 1.3.7__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {aistv-1.3.6 → aistv-1.3.7}/PKG-INFO +1 -1
- {aistv-1.3.6 → aistv-1.3.7}/aistv/core.py +57 -70
- {aistv-1.3.6 → aistv-1.3.7}/aistv.egg-info/PKG-INFO +1 -1
- {aistv-1.3.6 → aistv-1.3.7}/setup.py +1 -1
- {aistv-1.3.6 → aistv-1.3.7}/README.md +0 -0
- {aistv-1.3.6 → aistv-1.3.7}/aistv/__init__.py +0 -0
- {aistv-1.3.6 → aistv-1.3.7}/aistv/aistv.py +0 -0
- {aistv-1.3.6 → aistv-1.3.7}/aistv/trainer.py +0 -0
- {aistv-1.3.6 → aistv-1.3.7}/aistv.egg-info/SOURCES.txt +0 -0
- {aistv-1.3.6 → aistv-1.3.7}/aistv.egg-info/dependency_links.txt +0 -0
- {aistv-1.3.6 → aistv-1.3.7}/aistv.egg-info/requires.txt +0 -0
- {aistv-1.3.6 → aistv-1.3.7}/aistv.egg-info/top_level.txt +0 -0
- {aistv-1.3.6 → aistv-1.3.7}/setup.cfg +0 -0
@@ -1,10 +1,11 @@
|
|
1
|
-
# aistv.py
|
2
1
|
import subprocess
|
3
2
|
import sys
|
4
3
|
import sqlite3
|
5
4
|
import time
|
5
|
+
import requests
|
6
|
+
from groq import Groq
|
6
7
|
|
7
|
-
# Tự cài thư viện nếu thiếu
|
8
|
+
# Tự động cài thư viện nếu thiếu
|
8
9
|
def install_package(pkg):
|
9
10
|
try:
|
10
11
|
__import__(pkg)
|
@@ -14,69 +15,46 @@ def install_package(pkg):
|
|
14
15
|
install_package("groq")
|
15
16
|
install_package("requests")
|
16
17
|
|
17
|
-
|
18
|
+
# Cấu hình
|
19
|
+
DB_FILE = "usage.db"
|
20
|
+
SPAM_DELAY_SECONDS = 5
|
21
|
+
FREE_MAX_REQUESTS = 1
|
22
|
+
NORMAL_MAX_REQUESTS = 2
|
23
|
+
VIP_MAX_REQUESTS = None # Không giới hạn
|
18
24
|
|
19
25
|
API_KEYS = [
|
20
26
|
"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",
|
21
|
-
# Thêm key phụ tại đây nếu muốn:
|
22
|
-
# "your_second_key",
|
23
27
|
]
|
24
28
|
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
FREE_MAX_REQUESTS = 20
|
29
|
-
NORMAL_MAX_REQUESTS = 30
|
30
|
-
VIP_MAX_REQUESTS = None
|
31
|
-
|
32
|
-
TOKEN_VIP_SET = {
|
33
|
-
"aistv",
|
34
|
-
"phuc",
|
35
|
-
}
|
36
|
-
|
37
|
-
TOKEN_NORMAL_SET = {
|
38
|
-
"tokengsk_...",
|
39
|
-
}
|
40
|
-
|
41
|
-
MODEL_MAP = {
|
42
|
-
"Chat-ai-stv-3.5": "meta-llama/llama-3-8b-instruct",
|
43
|
-
"Chat-ai-stv-4.0": "meta-llama/llama-3-70b-instruct",
|
44
|
-
"Chat-ai-stv-2.3": "meta-llama/llama-4-maverick-17b-128e-instruct",
|
45
|
-
"Chat-ai-stv-4.5": "mistralai/mixtral-8x7b-instruct",
|
46
|
-
"Chat-ai-stv-5.0": "google/gemma-7b-it",
|
47
|
-
}
|
29
|
+
# Danh sách token
|
30
|
+
TOKEN_VIP_SET = {"aistv", "phuc"}
|
31
|
+
TOKEN_NORMAL_SET = {"tokengsk_...", "another_token..."}
|
48
32
|
|
49
33
|
class STVBot:
|
50
|
-
def __init__(self, token
|
51
|
-
if token is None:
|
52
|
-
raise ValueError("Bạn phải truyền token khi khởi tạo aistv")
|
53
|
-
if model is None:
|
54
|
-
raise ValueError("Bạn phải truyền model khi khởi tạo aistv")
|
55
|
-
|
56
|
-
# Bắt buộc model phải nằm trong MODEL_MAP, dùng key nguyên gốc
|
57
|
-
if model not in MODEL_MAP:
|
58
|
-
raise ValueError(f"Mô hình không hợp lệ: {model}. Dùng: {list(MODEL_MAP.keys())}")
|
59
|
-
|
60
|
-
self.model_key = model
|
61
|
-
self.model = MODEL_MAP[self.model_key]
|
62
|
-
self.system_prompt = system_prompt or "Tôi là AI STV, được phát triển bởi Trọng Phúc."
|
34
|
+
def __init__(self, token: str = None, system_prompt: str = None):
|
63
35
|
self.token = token
|
64
|
-
|
65
|
-
self.
|
66
|
-
self.
|
67
|
-
|
36
|
+
self.system_prompt = system_prompt or "Tôi là AI STV, được phát triển bởi Trọng Phúc."
|
37
|
+
self.api_keys = API_KEYS
|
38
|
+
self.api_index = 0
|
39
|
+
self.client = self._create_client()
|
40
|
+
self.model = "meta-llama/llama-4-maverick-17b-128e-instruct"
|
68
41
|
self.history = [{"role": "system", "content": self.system_prompt}]
|
69
42
|
|
70
|
-
|
71
|
-
|
43
|
+
# Xác định user & giới hạn
|
44
|
+
if not token:
|
45
|
+
self.user_id = "free_user"
|
46
|
+
self.max_requests = FREE_MAX_REQUESTS
|
47
|
+
elif token in TOKEN_VIP_SET:
|
72
48
|
self.user_id = token
|
49
|
+
self.max_requests = VIP_MAX_REQUESTS
|
73
50
|
elif token in TOKEN_NORMAL_SET:
|
74
|
-
self.max_requests = NORMAL_MAX_REQUESTS
|
75
51
|
self.user_id = token
|
52
|
+
self.max_requests = NORMAL_MAX_REQUESTS
|
76
53
|
else:
|
77
|
-
self.max_requests = FREE_MAX_REQUESTS
|
78
54
|
self.user_id = "free_user"
|
55
|
+
self.max_requests = FREE_MAX_REQUESTS
|
79
56
|
|
57
|
+
# CSDL lưu lượt dùng
|
80
58
|
self.conn = sqlite3.connect(DB_FILE, check_same_thread=False)
|
81
59
|
self.cursor = self.conn.cursor()
|
82
60
|
self.cursor.execute('''
|
@@ -90,6 +68,9 @@ class STVBot:
|
|
90
68
|
self.conn.commit()
|
91
69
|
self._init_user()
|
92
70
|
|
71
|
+
def _create_client(self):
|
72
|
+
return Groq(api_key=self.api_keys[self.api_index])
|
73
|
+
|
93
74
|
def _init_user(self):
|
94
75
|
today = time.strftime("%Y-%m-%d")
|
95
76
|
self.cursor.execute("SELECT * FROM usage WHERE user_id = ?", (self.user_id,))
|
@@ -103,7 +84,11 @@ class STVBot:
|
|
103
84
|
def _get_usage(self):
|
104
85
|
self.cursor.execute("SELECT count, last_time, last_date FROM usage WHERE user_id = ?", (self.user_id,))
|
105
86
|
row = self.cursor.fetchone()
|
106
|
-
return {
|
87
|
+
return {
|
88
|
+
"count": row[0],
|
89
|
+
"last_time": row[1],
|
90
|
+
"last_date": row[2]
|
91
|
+
} if row else {"count": 0, "last_time": 0, "last_date": time.strftime("%Y-%m-%d")}
|
107
92
|
|
108
93
|
def _save_usage(self, count, last_time, last_date):
|
109
94
|
self.cursor.execute(
|
@@ -112,51 +97,53 @@ class STVBot:
|
|
112
97
|
)
|
113
98
|
self.conn.commit()
|
114
99
|
|
115
|
-
def _switch_api_key(self):
|
116
|
-
if self.api_key_index + 1 < len(API_KEYS):
|
117
|
-
self.api_key_index += 1
|
118
|
-
self.client = Groq(api_key=API_KEYS[self.api_key_index])
|
119
|
-
return True
|
120
|
-
return False
|
121
|
-
|
122
100
|
def chat(self, prompt: str) -> str:
|
123
101
|
usage = self._get_usage()
|
124
102
|
now = time.time()
|
125
103
|
today = time.strftime("%Y-%m-%d")
|
126
104
|
|
105
|
+
# Reset lượt mỗi ngày
|
127
106
|
if usage["last_date"] != today:
|
128
107
|
usage["count"] = 0
|
129
108
|
usage["last_date"] = today
|
130
109
|
|
110
|
+
# Kiểm tra giới hạn lượt dùng
|
131
111
|
if self.max_requests is not None and usage["count"] >= self.max_requests:
|
132
|
-
return
|
112
|
+
return (
|
113
|
+
f"⚠️ Bạn đã dùng hết {self.max_requests} lượt trong ngày.\n"
|
114
|
+
"Hãy thử lại vào ngày mai hoặc liên hệ để nâng cấp quyền. https://discord.gg/Ze7RTExgdv"
|
115
|
+
)
|
133
116
|
|
117
|
+
# Kiểm tra spam
|
134
118
|
if now - usage["last_time"] < SPAM_DELAY_SECONDS:
|
135
|
-
|
136
|
-
return f"⚠️ Vui lòng
|
119
|
+
wait = SPAM_DELAY_SECONDS - int(now - usage["last_time"])
|
120
|
+
return f"⚠️ Vui lòng đợi {wait} giây nữa trước khi gửi câu hỏi tiếp theo."
|
137
121
|
|
138
122
|
self.history.append({"role": "user", "content": prompt})
|
123
|
+
tries = len(self.api_keys)
|
139
124
|
|
140
|
-
|
125
|
+
for _ in range(tries):
|
141
126
|
try:
|
142
|
-
|
127
|
+
self.client = self._create_client()
|
128
|
+
response = self.client.chat.completions.create(
|
143
129
|
messages=self.history,
|
144
130
|
model=self.model,
|
145
|
-
stream=False
|
131
|
+
stream=False
|
146
132
|
)
|
147
|
-
reply =
|
133
|
+
reply = response.choices[0].message.content.strip()
|
148
134
|
self.history.append({"role": "assistant", "content": reply})
|
149
135
|
|
136
|
+
# Lưu lượt dùng (trừ VIP)
|
150
137
|
if self.max_requests is not None:
|
151
138
|
usage["count"] += 1
|
152
139
|
usage["last_time"] = now
|
153
140
|
self._save_usage(usage["count"], usage["last_time"], usage["last_date"])
|
154
141
|
|
155
|
-
return reply
|
142
|
+
return reply
|
156
143
|
|
157
144
|
except Exception as e:
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
145
|
+
self.api_index += 1
|
146
|
+
if self.api_index >= len(self.api_keys):
|
147
|
+
return f"⚠️ Tất cả API key đều lỗi hoặc hết lượt.\nLỗi cuối cùng: {e}"
|
148
|
+
|
149
|
+
return "⚠️ Đã xảy ra lỗi. Vui lòng thử lại sau."
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|