neogram 9.3__tar.gz → 9.3.1__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.
- {neogram-9.3 → neogram-9.3.1}/PKG-INFO +4 -3
- {neogram-9.3 → neogram-9.3.1}/README.md +2 -2
- {neogram-9.3 → neogram-9.3.1}/neogram/ii.py +160 -18
- {neogram-9.3 → neogram-9.3.1}/neogram.egg-info/PKG-INFO +4 -3
- {neogram-9.3 → neogram-9.3.1}/neogram.egg-info/requires.txt +1 -0
- {neogram-9.3 → neogram-9.3.1}/setup.py +2 -2
- {neogram-9.3 → neogram-9.3.1}/LICENSE +0 -0
- {neogram-9.3 → neogram-9.3.1}/neogram/__init__.py +0 -0
- {neogram-9.3 → neogram-9.3.1}/neogram/fgram.py +0 -0
- {neogram-9.3 → neogram-9.3.1}/neogram.egg-info/SOURCES.txt +0 -0
- {neogram-9.3 → neogram-9.3.1}/neogram.egg-info/dependency_links.txt +0 -0
- {neogram-9.3 → neogram-9.3.1}/neogram.egg-info/top_level.txt +0 -0
- {neogram-9.3 → neogram-9.3.1}/setup.cfg +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: neogram
|
|
3
|
-
Version: 9.3
|
|
3
|
+
Version: 9.3.1
|
|
4
4
|
Summary: neogram is a lightweight Python module for working with the Telegram Bot API and AI. It combines simple Telegram workflows with powerful features like text and image generation, translation, and more.
|
|
5
5
|
Author: SiriLV
|
|
6
6
|
Author-email: siriteamrs@gmail.com
|
|
@@ -14,6 +14,7 @@ Description-Content-Type: text/markdown
|
|
|
14
14
|
License-File: LICENSE
|
|
15
15
|
Requires-Dist: requests>=2.32.5
|
|
16
16
|
Requires-Dist: bs4>=0.0.2
|
|
17
|
+
Requires-Dist: curl_cffi>=0.14.0
|
|
17
18
|
Dynamic: author
|
|
18
19
|
Dynamic: author-email
|
|
19
20
|
Dynamic: classifier
|
|
@@ -25,7 +26,7 @@ Dynamic: requires-dist
|
|
|
25
26
|
Dynamic: requires-python
|
|
26
27
|
Dynamic: summary
|
|
27
28
|
|
|
28
|
-
# 📚 Документация neogram v9.3
|
|
29
|
+
# 📚 Документация neogram v9.3.01
|
|
29
30
|
|
|
30
31
|
**Установка:**
|
|
31
32
|
|
|
@@ -88,7 +89,7 @@ bot = Bot(token="YOUR_TOKEN", timeout=60)
|
|
|
88
89
|
* `translate(text, lang)`: Перевод текста (через Google Translate).
|
|
89
90
|
* `short_url(long_url)`: Сокращение ссылок (clck.ru).
|
|
90
91
|
* `gen_ai_response(model, messages)`: Генерация ответа (Qwen/GPT OSS).
|
|
91
|
-
* `
|
|
92
|
+
* `perplexity_ask(model, query)`: Генерация через PerplexityAI
|
|
92
93
|
* `encode_base64(path)`: Кодирование файла в base64.
|
|
93
94
|
* `run_in_bg(func, ...)`: Запуск функции в отдельном потоке.
|
|
94
95
|
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
# 📚 Документация neogram v9.3
|
|
1
|
+
# 📚 Документация neogram v9.3.01
|
|
2
2
|
|
|
3
3
|
**Установка:**
|
|
4
4
|
|
|
@@ -61,7 +61,7 @@ bot = Bot(token="YOUR_TOKEN", timeout=60)
|
|
|
61
61
|
* `translate(text, lang)`: Перевод текста (через Google Translate).
|
|
62
62
|
* `short_url(long_url)`: Сокращение ссылок (clck.ru).
|
|
63
63
|
* `gen_ai_response(model, messages)`: Генерация ответа (Qwen/GPT OSS).
|
|
64
|
-
* `
|
|
64
|
+
* `perplexity_ask(model, query)`: Генерация через PerplexityAI
|
|
65
65
|
* `encode_base64(path)`: Кодирование файла в base64.
|
|
66
66
|
* `run_in_bg(func, ...)`: Запуск функции в отдельном потоке.
|
|
67
67
|
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import requests, json, base64, threading, re, bs4
|
|
2
2
|
from typing import Union, BinaryIO
|
|
3
|
+
from curl_cffi.requests import Session
|
|
3
4
|
|
|
4
5
|
#Блок - Нейросети
|
|
5
6
|
class OnlySQ:
|
|
@@ -56,28 +57,28 @@ class OnlySQ:
|
|
|
56
57
|
print(f"OnlySQ(get_models): {e}")
|
|
57
58
|
return []
|
|
58
59
|
|
|
59
|
-
def generate_answer(self, model: str = "gpt-5.2-chat", messages: dict = None) -> str:
|
|
60
|
+
def generate_answer(self, model: str = "gpt-5.2-chat", messages: dict = None, key: str = "openai") -> str:
|
|
60
61
|
"""Генерация ответа с использованием onlysq"""
|
|
61
62
|
try:
|
|
62
63
|
if messages is None:
|
|
63
64
|
raise ValueError("Забыли указать messages")
|
|
64
65
|
else:
|
|
65
66
|
payload = {"model": model, "request": {"messages": messages}}
|
|
66
|
-
response = requests.post("http://api.onlysq.ru/ai/v2", json=payload, headers={"Authorization":"Bearer
|
|
67
|
+
response = requests.post("http://api.onlysq.ru/ai/v2", json=payload, headers={"Authorization": f"Bearer {key}"})
|
|
67
68
|
response.raise_for_status()
|
|
68
69
|
return response.json()["choices"][0]["message"]["content"]
|
|
69
70
|
except Exception as e:
|
|
70
71
|
print(f"OnlySQ(generate_answer): {e}")
|
|
71
72
|
return "Error"
|
|
72
73
|
|
|
73
|
-
def generate_image(self, model: str = "flux", prompt: str = None, ratio: str = "16:9", filename: str = 'image.png') -> bool:
|
|
74
|
+
def generate_image(self, model: str = "flux", prompt: str = None, ratio: str = "16:9", filename: str = 'image.png', key: str = "openai") -> bool:
|
|
74
75
|
"""Генерация фотографии с использованием onlysq"""
|
|
75
76
|
try:
|
|
76
77
|
if prompt is None:
|
|
77
78
|
raise ValueError("Забыли указать prompt")
|
|
78
79
|
else:
|
|
79
80
|
payload = {"model": model, "prompt": prompt, "ratio": ratio}
|
|
80
|
-
response = requests.post("https://api.onlysq.ru/ai/imagen", json=payload, headers={"Authorization":"Bearer
|
|
81
|
+
response = requests.post("https://api.onlysq.ru/ai/imagen", json=payload, headers={"Authorization": f"Bearer {key}"})
|
|
81
82
|
if response.status_code == 200:
|
|
82
83
|
img_bytes = base64.b64decode(response.json()["files"][0])
|
|
83
84
|
with open(filename, 'wb') as f:
|
|
@@ -186,20 +187,161 @@ class Deef:
|
|
|
186
187
|
print(f"Deef(gen_ai_response): {e}")
|
|
187
188
|
return {"reasoning": "Error", "answer": "Error", "status": "unknown", "cluster_info": None}
|
|
188
189
|
|
|
189
|
-
def
|
|
190
|
-
"""
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
190
|
+
def perplexity_ask(self, model: str, query: str) -> dict:
|
|
191
|
+
"""
|
|
192
|
+
Вывод: словари с ключом 'type' и данными:
|
|
193
|
+
- {"type": "text", "content": "..."}
|
|
194
|
+
- {"type": "sources", "sources": [...]}
|
|
195
|
+
- {"type": "reasoning", "content": "...", "status": "thinking"|"done"}
|
|
196
|
+
- {"type": "media", "items": [...]}
|
|
197
|
+
- {"type": "followups", "followups": [...]}
|
|
198
|
+
- {"type": "finish", "reason": "stop"}
|
|
199
|
+
"""
|
|
200
|
+
MODELS = [
|
|
201
|
+
"turbo", "gpt41", "gpt5", "gpt5_thinking", "o3",
|
|
202
|
+
"o3pro", "claude2", "claude37sonnetthinking", "claude40opus", "claude40opusthinking",
|
|
203
|
+
"claude41opusthinking", "claude45sonnet", "claude45sonnetthinking", "experimental", "grok",
|
|
204
|
+
"grok4", "gemini2flash", "pplx_pro", "pplx_pro_upgraded", "pplx_alpha",
|
|
205
|
+
"pplx_beta", "comet_max_assistant", "o3_research", "o3pro_research", "claude40sonnet_research",
|
|
206
|
+
"claude40sonnetthinking_research", "claude40opus_research", "claude40opusthinking_research", "o3_labs", "o3pro_labs",
|
|
207
|
+
"claude40sonnetthinking_labs", "claude40opusthinking_labs", "o4mini", "o1", "gpt4o",
|
|
208
|
+
"gpt45", "gpt4", "o3mini", "claude35haiku", "llama_x_large",
|
|
209
|
+
"mistral", "claude3opus", "gemini", "pplx_reasoning", "r1"]
|
|
210
|
+
BASE_URL = "https://www.perplexity.ai"
|
|
211
|
+
if model not in MODELS:
|
|
212
|
+
model = MODELS[0]
|
|
213
|
+
frontend_uid = str(uuid.uuid4())
|
|
214
|
+
frontend_context_uuid = str(uuid.uuid4())
|
|
215
|
+
visitor_id = str(uuid.uuid4())
|
|
216
|
+
headers = {
|
|
217
|
+
"accept": "text/event-stream",
|
|
218
|
+
"accept-language": "en-US,en;q=0.9",
|
|
219
|
+
"cache-control": "no-cache",
|
|
220
|
+
"content-type": "application/json",
|
|
221
|
+
"origin": BASE_URL,
|
|
222
|
+
"referer": f"{BASE_URL}/",
|
|
223
|
+
"user-agent": "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/140.0.0.0 Safari/537.36",
|
|
224
|
+
"x-perplexity-request-reason": "perplexity-query-state-provider"}
|
|
225
|
+
with Session(headers=headers, timeout=300, impersonate="chrome") as session:
|
|
226
|
+
resp = session.get(f"{BASE_URL}/api/auth/session")
|
|
227
|
+
user_id = resp.json().get("user", {}).get("id")
|
|
228
|
+
if model == "auto":
|
|
229
|
+
model = "pplx_pro" if user_id else "turbo"
|
|
230
|
+
data = {
|
|
231
|
+
"params": {
|
|
232
|
+
"attachments": [],
|
|
233
|
+
"language": "en-US",
|
|
234
|
+
"timezone": "America/New_York",
|
|
235
|
+
"followup_source": "link",
|
|
236
|
+
"search_focus": "internet",
|
|
237
|
+
"source": "default",
|
|
238
|
+
"sources": ["edgar", "social", "web", "scholar"],
|
|
239
|
+
"frontend_uuid": frontend_uid,
|
|
240
|
+
"mode": "concise",
|
|
241
|
+
"model_preference": model,
|
|
242
|
+
"visitor_id": visitor_id,
|
|
243
|
+
"frontend_context_uuid": frontend_context_uuid,
|
|
244
|
+
"prompt_source": "user",
|
|
245
|
+
"query_source": "followup",
|
|
246
|
+
"use_schematized_api": True,
|
|
247
|
+
"supported_block_use_cases": [
|
|
248
|
+
"answer_modes", "media_items", "knowledge_cards", "inline_entity_cards",
|
|
249
|
+
"place_widgets", "finance_widgets", "prediction_market_widgets", "sports_widgets",
|
|
250
|
+
"flight_status_widgets", "news_widgets", "shopping_widgets", "jobs_widgets",
|
|
251
|
+
"search_result_widgets", "inline_images", "inline_assets", "placeholder_cards",
|
|
252
|
+
"diff_blocks", "inline_knowledge_cards", "entity_group_v2", "refinement_filters",
|
|
253
|
+
"canvas_mode", "maps_preview", "answer_tabs", "price_comparison_widgets",
|
|
254
|
+
"preserve_latex", "generic_onboarding_widgets", "in_context_suggestions"
|
|
255
|
+
],
|
|
256
|
+
"version": "2.18"
|
|
257
|
+
}, "query_str": query}
|
|
258
|
+
response = session.post(f"{BASE_URL}/rest/sse/perplexity_ask", json=data)
|
|
259
|
+
if response.status_code >= 400:
|
|
260
|
+
raise Exception(f"HTTP {response.status_code}")
|
|
261
|
+
content = response.content
|
|
262
|
+
if isinstance(content, bytes):
|
|
263
|
+
content = content.decode('utf-8')
|
|
264
|
+
full_response = ""
|
|
265
|
+
full_reasoning = ""
|
|
266
|
+
sources_sent = False
|
|
267
|
+
for line in content.split('\n'):
|
|
268
|
+
line = line.strip()
|
|
269
|
+
if not line.startswith('data: '):
|
|
270
|
+
continue
|
|
271
|
+
data_str = line[6:]
|
|
272
|
+
if not data_str or data_str == '[DONE]':
|
|
273
|
+
continue
|
|
274
|
+
try:
|
|
275
|
+
json_data = json.loads(data_str)
|
|
276
|
+
except json.JSONDecodeError:
|
|
277
|
+
continue
|
|
278
|
+
for block in json_data.get("blocks", []):
|
|
279
|
+
intended_usage = block.get("intended_usage", "")
|
|
280
|
+
if intended_usage == "sources_answer_mode":
|
|
281
|
+
sources_block = block.get("sources_mode_block", {})
|
|
282
|
+
web_results = sources_block.get("web_results", [])
|
|
283
|
+
if web_results and not sources_sent:
|
|
284
|
+
yield {"type": "sources", "sources": web_results}
|
|
285
|
+
sources_sent = True
|
|
286
|
+
continue
|
|
287
|
+
if intended_usage == "media_items":
|
|
288
|
+
media_block = block.get("media_block", {})
|
|
289
|
+
media_items = media_block.get("media_items", [])
|
|
290
|
+
if media_items:
|
|
291
|
+
items = []
|
|
292
|
+
for item in media_items:
|
|
293
|
+
items.append({
|
|
294
|
+
"media_type": item.get("medium", "unknown"),
|
|
295
|
+
"url": item.get("url", ""),
|
|
296
|
+
"title": item.get("name", ""),
|
|
297
|
+
"width": item.get("image_width"),
|
|
298
|
+
"height": item.get("image_height")
|
|
299
|
+
})
|
|
300
|
+
yield {"type": "media", "items": items}
|
|
301
|
+
continue
|
|
302
|
+
if intended_usage in ("pro_search_steps", "plan"):
|
|
303
|
+
plan_block = block.get("plan_block", {})
|
|
304
|
+
if plan_block:
|
|
305
|
+
goals = plan_block.get("goals", [])
|
|
306
|
+
progress = plan_block.get("progress", "")
|
|
307
|
+
for goal in goals:
|
|
308
|
+
if isinstance(goal, str) and goal:
|
|
309
|
+
yield {"type": "reasoning", "content": goal, "status": "thinking"}
|
|
310
|
+
if progress == "DONE":
|
|
311
|
+
yield {"type": "reasoning", "content": "", "status": "done"}
|
|
312
|
+
diff_block = block.get("diff_block", {})
|
|
313
|
+
if diff_block.get("field") == "plan_block":
|
|
314
|
+
for patch in diff_block.get("patches", []):
|
|
315
|
+
if patch.get("path", "").startswith("/goals"):
|
|
316
|
+
value = patch.get("value", "")
|
|
317
|
+
if isinstance(value, str) and value:
|
|
318
|
+
new_reasoning = value[len(full_reasoning):] if value.startswith(full_reasoning) else value
|
|
319
|
+
if new_reasoning:
|
|
320
|
+
full_reasoning = value if value.startswith(full_reasoning) else full_reasoning + value
|
|
321
|
+
yield {"type": "reasoning", "content": new_reasoning, "status": "thinking"}
|
|
322
|
+
continue
|
|
323
|
+
if intended_usage != "ask_text_0_markdown":
|
|
324
|
+
continue
|
|
325
|
+
diff_block = block.get("diff_block", {})
|
|
326
|
+
if diff_block.get("field") != "markdown_block":
|
|
327
|
+
continue
|
|
328
|
+
for patch in diff_block.get("patches", []):
|
|
329
|
+
value = patch.get("value", "")
|
|
330
|
+
if isinstance(value, dict) and "chunks" in value:
|
|
331
|
+
text = "".join(value.get("chunks", []))
|
|
332
|
+
if text and len(text) > len(full_response):
|
|
333
|
+
new_text = text[len(full_response):]
|
|
334
|
+
full_response = text
|
|
335
|
+
yield {"type": "text", "content": new_text}
|
|
336
|
+
elif patch.get("op") == "add" and isinstance(value, str) and value:
|
|
337
|
+
full_response += value
|
|
338
|
+
yield {"type": "text", "content": value}
|
|
339
|
+
if "related_query_items" in json_data:
|
|
340
|
+
followups = [i.get("text", "") for i in json_data["related_query_items"]]
|
|
341
|
+
if followups:
|
|
342
|
+
yield {"type": "followups", "followups": followups}
|
|
343
|
+
if json_data.get("status") == "COMPLETED":
|
|
344
|
+
yield {"type": "finish", "reason": "stop"}
|
|
203
345
|
|
|
204
346
|
|
|
205
347
|
class ChatGPT:
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: neogram
|
|
3
|
-
Version: 9.3
|
|
3
|
+
Version: 9.3.1
|
|
4
4
|
Summary: neogram is a lightweight Python module for working with the Telegram Bot API and AI. It combines simple Telegram workflows with powerful features like text and image generation, translation, and more.
|
|
5
5
|
Author: SiriLV
|
|
6
6
|
Author-email: siriteamrs@gmail.com
|
|
@@ -14,6 +14,7 @@ Description-Content-Type: text/markdown
|
|
|
14
14
|
License-File: LICENSE
|
|
15
15
|
Requires-Dist: requests>=2.32.5
|
|
16
16
|
Requires-Dist: bs4>=0.0.2
|
|
17
|
+
Requires-Dist: curl_cffi>=0.14.0
|
|
17
18
|
Dynamic: author
|
|
18
19
|
Dynamic: author-email
|
|
19
20
|
Dynamic: classifier
|
|
@@ -25,7 +26,7 @@ Dynamic: requires-dist
|
|
|
25
26
|
Dynamic: requires-python
|
|
26
27
|
Dynamic: summary
|
|
27
28
|
|
|
28
|
-
# 📚 Документация neogram v9.3
|
|
29
|
+
# 📚 Документация neogram v9.3.01
|
|
29
30
|
|
|
30
31
|
**Установка:**
|
|
31
32
|
|
|
@@ -88,7 +89,7 @@ bot = Bot(token="YOUR_TOKEN", timeout=60)
|
|
|
88
89
|
* `translate(text, lang)`: Перевод текста (через Google Translate).
|
|
89
90
|
* `short_url(long_url)`: Сокращение ссылок (clck.ru).
|
|
90
91
|
* `gen_ai_response(model, messages)`: Генерация ответа (Qwen/GPT OSS).
|
|
91
|
-
* `
|
|
92
|
+
* `perplexity_ask(model, query)`: Генерация через PerplexityAI
|
|
92
93
|
* `encode_base64(path)`: Кодирование файла в base64.
|
|
93
94
|
* `run_in_bg(func, ...)`: Запуск функции в отдельном потоке.
|
|
94
95
|
|
|
@@ -2,13 +2,13 @@ from setuptools import setup, find_packages
|
|
|
2
2
|
|
|
3
3
|
setup(
|
|
4
4
|
name='neogram',
|
|
5
|
-
version='9.3',
|
|
5
|
+
version='9.3.01',
|
|
6
6
|
description='neogram is a lightweight Python module for working with the Telegram Bot API and AI. It combines simple Telegram workflows with powerful features like text and image generation, translation, and more.',
|
|
7
7
|
author='SiriLV',
|
|
8
8
|
author_email='siriteamrs@gmail.com',
|
|
9
9
|
packages=find_packages(),
|
|
10
10
|
python_requires='>=3.10',
|
|
11
|
-
install_requires=['requests>=2.32.5', 'bs4>=0.0.2'],
|
|
11
|
+
install_requires=['requests>=2.32.5', 'bs4>=0.0.2', 'curl_cffi>=0.14.0'],
|
|
12
12
|
classifiers=[
|
|
13
13
|
'Programming Language :: Python :: 3',
|
|
14
14
|
'Programming Language :: Python :: 3.10',
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|