Compare commits

...

1 Commits

Author SHA1 Message Date
hsafaei
6acabcf52d untill reason button 2026-02-01 09:04:29 +00:00
12 changed files with 1518 additions and 372 deletions

View File

@ -369,10 +369,11 @@ class Formatter:
self,
_input: Union[List[RuleRelation], str],
header="نتایج اولیه مغایرت های احتمالی :\n",
end_button:List=[],
):
if isinstance(_input, str):
_input = self.form_law_chat(_input)
return _input, [], []
return _input, [],
else:
chunks = []
buttons = []
@ -384,19 +385,20 @@ class Formatter:
groups[title].add(item.db_rule.section_id)
current = header
for idx, (qanon_title, section_ids) in enumerate(groups.items(), start=1):
for idx, (qanon_title, sections_data) in enumerate(groups.items(), start=1):
block_lines = [f"{self.number(idx)} در قانون {self.bold(qanon_title)}"]
sample_items_by_section = {}
for item in _input:
if (
item.db_rule.qanon_title == qanon_title
and item.db_rule.section_id in section_ids
and item.db_rule.section_id in sections_data
):
sid = item.db_rule.section_id
if sid not in sample_items_by_section:
sample_items_by_section[sid] = item
for sub_idx, section_id in enumerate(sorted(section_ids), start=1):
for sub_idx, section_id in enumerate(sorted(sections_data), start=1):
item = sample_items_by_section[section_id] # representative item
link = self.__make_link_qs(src=section_id)
@ -451,7 +453,91 @@ class Formatter:
for i in v:
mapping_data[k].append(input_dict[i])
for i in end_button:
buttons.append(i)
return chunks, buttons, mapping_data
async def structed_form_subject_unity(
self,
_input: Union[List[RuleRelation], str],
header="نتایج بررسی وحدت موضوعی :\n",
end_button:List=[],
):
"""
خروجی به صورت ساختارمند :
[پیام-دکمه], ...
"""
if isinstance(_input, str):
_input = self.form_law_chat(_input)
return _input, [], []
else:
chunks_data = []
groups_data = defaultdict(set)
main_idx = 1
current = header
# گروه بندی بر اساس عنوان قانون
for item in _input:
qanon_id = item.db_rule.qanon_id
is_unity = item.subject_unity.has_subject_unity
if is_unity != 'no':
groups_data[qanon_id].add(
item
)
for _idx, (qanon_id, rule_data) in enumerate(groups_data.items(), start=1):
# for idx, (qanon_title, rule_data) in enumerate(groups.items(), start=1):
for _idx2, single_data in enumerate(rule_data, start=1):
if _idx2 == 1:
qanon_title = single_data.db_rule.qanon_title
block_lines = [self.bold(current)]
block_lines += [f" در قانون {self.bold(qanon_title)}"]
link = self.__make_link_qs(src=single_data.db_rule.section_id)
unity = single_data.subject_unity
if not unity:
block_lines.append("\t\t")
continue
if unity.has_subject_unity == "yes":
block_lines.append(f"توضیح {main_idx} بر اساس {link}:")
block_lines.append(f"\t{unity.reasoning or ''}")
elif unity.has_subject_unity == "yes_under_assumptions":
block_lines.append(f"توضیح {main_idx} بر اساس {link}:")
block_lines.append(f"\t{unity.reasoning or ''}")
block_lines.append("\tتوضیحات بیشتر (فرضیات لازم):")
block_lines.append(f"\t{unity.required_assumptions or ''}")
main_idx += 1
m_text = "\n".join(block_lines)
# Auto-chunk based on length
if len(m_text) > MAX_LEN:
# chunking m_text
pass
else:
print(f'structed_form_subject_unity; {len(m_text)}')
_button = [[
{
"text": f"بررسی مغایرت",
"callback_data": f"subject_unities:qq:{qanon_id}",
}
]]
# end_button
if _idx == len(groups_data):
m_button = _button + end_button
else:
m_button = _button
chunks_data.append([m_text, m_button])
print(f'structed_form_subject_unity')
return chunks_data, groups_data
async def form_rule_making(
self, _input, header="گزاره های حقوقی زیر استخراج شد:\n\n", footer=None
@ -591,6 +677,35 @@ class Formatter:
return ["هیچ ماده مرتبطی یافت نشد!"]
async def form2_ss_rules(self, _input: List[SemanticSearchP2P], header):
if len(_input) > 1:
chunks = []
main_id = 0
block = [header]
# -------- 1. group by qanon_id / qanon_title
groups_data = defaultdict(set)
for item in _input:
title = item.db_rule.qanon_title
groups_data[title].add(item)
for _idx, (qanon_title, sections_data) in enumerate(groups_data.items(), start=1):
main_id += 1
block += [f"{self.number(main_id)} در قانون {self.bold(qanon_title)}:"]
for _idx2, sec_data in enumerate(sections_data, start=1):
block +=[f"تشابه با گزاره های حقوقی: {self.bold(sec_data.db_rule.section_full_path)} {self.__make_link_qs(sec_data.db_rule.section_id)} یافت شد."]
if len("\n".join(block)) > self.max_len:
chunks.append("\n".join(block))
block=[header]
if block and "".join(block) != header:
chunks.append("\n".join(block))
return chunks
return ["هیچ ماده مرتبطی یافت نشد!"]
async def form_conflict_detection(
self, _input: RuleRelation, header="نتیجه تشخیص مغایرت :\n"
):
@ -601,7 +716,7 @@ class Formatter:
current += f"به صورت خلاصه {_input.conflict_detection.has_confict}\n"
current += f"توضیحات : {_input.conflict_detection.explanation_of_conflict}\n"
return current
return [current]
async def form_conflict_type_detection(
self, _input: RuleRelation, header="نتیجه تشخیص نوع مغایرت :\n"
@ -613,7 +728,7 @@ class Formatter:
current += f"به صورت خلاصه {_input.conflict_type_detection.conflict_type}\n"
current += f"توضیحات : {_input.conflict_type_detection.explanation_of_type}\n"
return current
return [current]
async def form_relation_identification(
self, _input: RuleRelation, header="نتیجه رابطه مغایرت :\n"
@ -625,25 +740,23 @@ class Formatter:
current += f"به صورت خلاصه {_input.relation_identification.relation_type}\n"
current += f"توضیحات : {_input.relation_identification.reasoning}\n"
return current
return [current]
async def form_evaluation(
self, _input: Evaluation, header="نتیجه نهایی بررسی مغایرت :\n"
):
current = header
current = [header]
# ساخت لینک
# _link = self.__make_link_qs(src=_input.db_rule.section_id)
current += f"1. آیا ارزیابی وحدت موضوع صحیح است؟ {_input.is_subject_unity_assessment_correct}\n"
current += f"2. آیا ارزیابی تشخیص نوع درست است ؟ {_input.is_conflict_detection_correct}\n"
current += f"3. آیا ارزیابی نوع درست است ؟ {_input.is_conflict_type_detection_correct}\n"
current += (
f"4. رابطه مغایرت چطور؟ {_input.is_relation_type_detection_correct}\n"
)
current += f"5. نوع رابطه ؟ {_input.valid_relation_type}\n"
current += f"6.توضیح بیشتر: {_input.comments}\n"
current += [f"1. آیا ارزیابی وحدت موضوع صحیح است؟ {_input.is_subject_unity_assessment_correct}"]
current += [f"2. آیا ارزیابی تشخیص نوع درست است ؟ {_input.is_conflict_detection_correct}"]
current += [f"3. آیا ارزیابی نوع درست است ؟ {_input.is_conflict_type_detection_correct}"]
current += [f"4. رابطه مغایرت چطور؟ {_input.is_relation_type_detection_correct}"]
current += [f"5. نوع رابطه ؟ {_input.valid_relation_type}"]
current += [f"6.توضیح بیشتر: {_input.comments}"]
return current
return "\n".join(current)
async def from_law_writing_policy(
self, _input_dict: Dict, header: str

View File

@ -30,7 +30,7 @@ class Operation:
url="new/semantic_search",
)
return BMNewSemanticSearchOutput.parse_obj(result)
return BMNewSemanticSearchOutput.model_validate(result)
async def stream_search_in_law(
self, query: str, limit: int, rerank_model: str, embed_model: str
@ -113,7 +113,7 @@ class Operation:
url="/single/semantic_search/run_chat",
)
print(f"chat_in_law {result}")
return ChatLaw.parse_obj(result)
return ChatLaw.model_validate(result)
async def title_repeated(
self,

View File

@ -1,19 +1,33 @@
################# modularity
### import from external-package
# from fastapi import FastAPI, Request, HTTPException
# import requests, logging, asyncio, httpx, os, uuid, traceback, orjson, copy, uvicorn, time, re
# from dotenv import load_dotenv
# from pathlib import Path
# from time import sleep
# from enum import Enum
# from typing import Dict
# from utils.base_model import RuleRelation
################# Static-Ui-Controll
### bottuns
B_PREVIOUS = "⬅️ مرحله قبل"
B_HOME = "🏠 خانه"
B_10MORE = "بارگذاری نتایج بیشتر 10+"
B_MORE_EFFORT = "بررسی عمیق تر"
B_STOP_PROCCESS = "توقف عملیات در حال اجراء"
B_WAIT = "⌛ در حال پردازش درخواست شما هستم..."
B_CHOICE_SUMMARY = "نمایش به صورت خلاصه"
B_CHOICE_FULL= "نمایش به صورت کامل"
### static-text-message/callback
"""
پیام های رزرو شده برای در نظر گرفتن بعنوان CALLBACK و دکمه های کیبورد
"""
MC_JOST_JO = "جستجو"
MC_GOFT_GO = "گفتگو"
MC_HOME = "بازگشت به خانه"
### State-Static-Messages
SM_CHOICE = """لطفا یک مورد را انتخاب کنید:""" #برای انتخاب بین چند دکمه
#################################################
# پارامتر های کلی
#################################################
### Core-Options
## Delay-Time
D_TIME_CHAT = 0.05
D_TIME_UI_TEMP_CHAT = 0.4
## limit
REQUEST_FREEZE_LIMIT = 3
MAX_RAG_LIMIT = 100
BUSY_TEXT = "⏳ درخواست قبلی شما در حال پردازش هست، لطفا تا اتمام آن منتظر بمانید ⏳"
EFFORT = "low"
MAX_LIMIT_RAG = 100 # بیشینه تعدادی که rag برمی گرداند
STEP_RAG = 10 # مقداری که هر مرحله rag اضافه میکند با فشردن نمایش بیشتر more
@ -24,3 +38,4 @@ QQ_WEB_LINK = (
"https://majles.tavasi.ir/entity/navigation/view/qasection/" # آدرس صفحه qq ها
)
REF_TEXT = "«منبع»" # برای نمایش منبع

271
inProcees_md.txt Normal file
View File

@ -0,0 +1,271 @@
result ==> # Flowchart: Bale-Bot Backend System
## Main Application Flow
```
┌─────────────────────────────────────┐
│ main.py │
└──────────┬────────────────────────┘
┌─────────────────────────────────────┐
│ Lifespan Manager (Startup) │
│ ┌─────────────────────────────┐ │
│ │ Load .env variables │ │
│ │ Validate required vars │ │
│ │ Initialize ElasticHelper │ │
│ │ Set webhook URL │ │
│ │ Initialize UserManager │ │
│ │ Initialize Formatter │ │
│ │ Initialize RequestManager │ │
│ │ Initialize Operation │ │
│ │ Initialize BaleBotCore │ │
│ └─────────────────────────────┘ │
└──────────┬────────────────────────┘
┌─────────────────────────────────────┐
│ Application Factory │
│ ┌─────────────────────────────┐ │
│ │ Create FastAPI app │ │
│ │ Add CORS middleware │ │
│ │ Add health routes (/, /ping)│ │
│ │ Include Bale router │ │
│ └─────────────────────────────┘ │
└──────────┬────────────────────────┘
┌─────────────────────────────────────┐
│ FastAPI App Running │
└─────────────────────────────────────┘
```
## Core Classes Flow
### 1. ElasticHelper Class
```
┌─────────────────────────────────────┐
│ ElasticHelper │
├─────────────────────────────────────┤
│ __init__(es_url, es_pass, es_user) │
│ ┌─────────────────────────────┐ │
│ │ Connect to Elasticsearch │ │
│ │ Retry connection 10 times │ │
│ └─────────────────────────────┘ │
│ │
│ search(**params) │
│ get_document(index, id) │
│ exist_document(index, id) │
│ update_index_doc(is_update, ...) │
└─────────────────────────────────────┘
```
### 2. Formatter Class
```
┌─────────────────────────────────────┐
│ Formatter │
├─────────────────────────────────────┤
│ __init__(max_len) │
│ ┌─────────────────────────────┐ │
│ │ Initialize formatting tools │ │
│ │ Number mapping │ │
│ └─────────────────────────────┘ │
│ │
│ __getattr__(name) │
│ _bold(text) │
│ _number(value) │
│ _pretier1(text) │
│ __make_link_qq(src) │
│ __make_link_qs(src) │
│ │
│ form_search_in_law_rules(...) │
│ form_search_in_law(...) │
│ form_law_chat(answer_text) │
│ form_title_repeated(...) │
│ form_chat(llm_text, header) │
│ form_llm_answer_chat(...) │
│ form_subject_unity(...) │
│ structed_form_subject_unity(...) │
│ form_rule_making(...) │
│ get_asl(_in) │
│ get_in_form_single(asl, ...) │
│ form_constitution(input) │
│ form_constitution_low(...) │
│ form_ss_rules(...) │
│ form2_ss_rules(...) │
│ form_conflict_detection(...) │
│ form_conflict_type_detection(...) │
│ form_relation_identification(...) │
│ form_evaluation(...) │
│ from_law_writing_policy(...) │
└─────────────────────────────────────┘
```
### 3. RequestManager Class
```
┌─────────────────────────────────────┐
│ RequestManager │
├─────────────────────────────────────┤
│ __init__(host_url) │
│ ┌─────────────────────────────┐ │
│ │ Set base URL │ │
│ │ Define task URLs │ │
│ └─────────────────────────────┘ │
│ │
│ get_result(payload, url, ...) │
│ ┌─────────────────────────────┐ │
│ │ Async HTTP POST request │ │
│ │ Handle timeouts/errors │ │
│ └─────────────────────────────┘ │
│ │
│ stream_result(url, payload) │
│ ┌─────────────────────────────┐ │
│ │ Stream HTTP POST response │ │
│ │ Yield JSON lines │ │
│ └─────────────────────────────┘ │
└─────────────────────────────────────┘
```
### 4. Operation Class
```
┌─────────────────────────────────────┐
│ Operation │
├─────────────────────────────────────┤
│ __init__(request_manager) │
│ │
│ search_in_law(query, limit, ...) │
│ stream_search_in_law(...) │
│ stream_rule_making(...) │
│ stream_chat_in_law(...) │
│ stream_rule_semantic_search(...) │
│ chat_in_law(query, effort, ...) │
│ title_repeated(qanontitle, ...) │
│ talk(query) │
│ conflict_qanon_asasi_low(...) │
│ conflict_qanon_asasi_steps(...) │
│ stream_logical_chat_in_law(...) │
│ conflict_law_writing_policy(...) │
└─────────────────────────────────────┘
```
### 5. UserManager Class
```
┌─────────────────────────────────────┐
│ UserManager │
├─────────────────────────────────────┤
│ __init__() │
│ ┌─────────────────────────────┐ │
│ │ Load VIP usernames │ │
│ │ Load temporary data │ │
│ └─────────────────────────────┘ │
│ │
│ get_or_create(update) │
│ ┌─────────────────────────────┐ │
│ │ Extract user info │ │
│ │ Check VIP status │ │
│ │ Create/update user object │ │
│ └─────────────────────────────┘ │
└─────────────────────────────────────┘
```
### 6. BaleBotCore Class
```
┌─────────────────────────────────────┐
│ BaleBotCore │
├─────────────────────────────────────┤
│ __init__(...) │
│ ┌─────────────────────────────┐ │
│ │ Initialize UI handler │ │
│ │ Setup components │ │
│ └─────────────────────────────┘ │
│ │
│ render_user_state(user) │
│ ┌─────────────────────────────┐ │
│ │ Get user state │ │
│ │ Call appropriate handler │ │
│ └─────────────────────────────┘ │
│ │
│ render_update(update) │
│ ┌─────────────────────────────┐ │
│ │ Process incoming updates │ │
│ │ Route to handlers │ │
│ └─────────────────────────────┘ │
│ │
│ handle_main(user) │
│ handle_search_in_law(user) │
│ handle_rule_making(user) │
│ handle_chat_in_law(user) │
│ handle_qanon_title_repeat(user) │
│ handle_talk(user) │
│ handle_logical_chat_in_law(user) │
│ handle_conflict_qanon_asasi(user) │
│ handle_conflict_law_writing_policy(user) │
│ handle_subject_unities_to_evalution(user) │
│ handle_summary_conflict_all_qavanin(user) │
│ handle_full_conflict_all_qavanin(user) │
│ handle_conflict_general_policy(user) │
│ handle_advanced_check_conflict(user) │
│ handle_stream_chat(user) │
│ handle_beta(user) │
│ │
│ save_to_db(user, data) │
└─────────────────────────────────────┘
```
### 7. BaleBotBase Class
```
┌─────────────────────────────────────┐
│ BaleBotBase │
├─────────────────────────────────────┤
│ __init__(send_msg_url, ...) │
│ │
│ delete_bale_message(chat_id, message_id) │
│ update_bale_message(user, text, buttons) │
│ serialize(obj) │
│ normalize_messages(...) │
│ send_message_helper(...) │
│ send_bale_message(...) │
└─────────────────────────────────────┘
```
### 8. BaleBotUI Class
```
┌─────────────────────────────────────┐
│ BaleBotUI │
├─────────────────────────────────────┤
│ __init__(delay_time, ...) │
│ ┌─────────────────────────────┐ │
│ │ Initialize heartbeat settings │ │
│ └─────────────────────────────┘ │
│ │
│ active(user) │
│ cancel(user) │
│ create(user, main_text, waiting_list) │
│ heartbeat_loop(user, waiting_list) │
└─────────────────────────────────────┘
```
### 9. StackManager Class
```
┌─────────────────────────────────────┐
│ StackManager │
├─────────────────────────────────────┤
│ push(output_pure_data, ...) │
│ last_item(user) │
│ get_last_item_metadata(user) │
│ prev_item(user) │
│ get(user, name) │
│ cleanup(user) │
│ set_runtime(user, index, runtime_ms) │
└─────────────────────────────────────┘
```
## Data Flow Between Components
```
┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐
│ FastAPI App │───▶│ BaleBotCore │───▶│ RequestManager │
└─────────────────┘ │ │ │ │
│ │ │ │
│ │ │ │

View File

@ -5,7 +5,7 @@ from core.core import ElasticHelper, Formatter, RequestManager
from fastapi.middleware.cors import CORSMiddleware
from router.bale.bale import router as bale_router
from router.bale.bale import initialize_webhook
from router.bale.bale_handle import BaleBot, UserManager
from router.bale.bale_handle import BaleBotCore, UserManager
from core.operation import Operation
from dotenv import load_dotenv
import os
@ -72,15 +72,17 @@ async def lifespan(app: FastAPI):
request_manager=app.state.request_manager,
)
# بله بات
bale_bot = BaleBot(
bale_bot = BaleBotCore(
operation=app.state.operation,
user_manager=app.state.user_manager,
es_helper=app.state.es_helper,
es_index_name=app.state.es_index_name,
token=app.state.bale_token,
formatter= app.state.formatter,
back_end_url = BACK_END_URL,
request_manager = app.state.request_manager,
send_message_url = f"https://tapi.bale.ai/bot{TOKEN}/sendMessage",
delete_message_url = f"https://tapi.bale.ai/bot{TOKEN}/deleteMessage",
update_message_url = f"https://tapi.bale.ai/bot{TOKEN}/editMessageText",
)
app.state.bale_bot = bale_bot
print("✅✅✅ Bale-Bot Initialized ✅✅✅")

View File

@ -9,7 +9,7 @@ Operation (logic layer)
└── return OperationResult
BaleBot (delivery / interface layer)
BaleBotCore (delivery / interface layer)
├── دریافت user
├── صدا زدن Operation
@ -19,4 +19,83 @@ BaleBot (delivery / interface layer)
# Logic & Flow
Operation → منطق، پردازش، گرفتن دیتا، تصمیم‌گیری
BaleBot → ورودی/خروجی، ارتباط با بله، فرمت پیام، دکمه‌ها، مدیریت state کاربر
BaleBotCore → ورودی/خروجی، ارتباط با بله، فرمت پیام، دکمه‌ها، مدیریت state کاربر
# FlowChart
/
└── main.py
│ └── fast-api app
├── core
│ └── core.py
│ ├── class Formatter : فرمت دهی و مدیریت استایل ها و UI
│ ├── class RequestManager : درخواست ها و داده ها را از بک اند میگیرد در دو نوع async (chunk-chunk) و ساده
│ └── class ElasticHelper : مدیریت و ارتباط با الاستیک سرچ
├── router
│ └── bale
│ ├── bale.py
│ │ ├── func webhook : دریافت داده از بله
│ │ └── func initialize_webhook : شناساندن ربات به بله
│ ├── bale_handle.py
│ │ ├── class BaleBotBase : برای مدیریت پیام ها و دکمه ها و 3 url send, update, delet ارتباط با سرور بله
│ │ ├── class BaleBotUI : مدیریت پیام های موقتی
│ │ ├── class StackManager : مدیریت داده های کاربر در پشته یا stack
│ │ └── class BaleBotCore : ساختار ربات و انجام state ها
│ │ ├── func render_update : مسئول گرفتن داده از بله به دو صورت BaleStartMessage یا BaleCallbackQuery
│ │ ├── func render_user_state : وظیفه مدیریت و پاس دادن هر ورودی به بر اساس state به تابع موردنظر
│ │ ├── func handle_previous_message : دسترسی به پیام مرحله قبل (بزودی باید با stack هندل شود)
│ │ ├── func handle_main : صفحه اول - حذف کننده داده ها و ریست داده ها
│ │ ├── func handle_search_in_law :
│ │ ├── func handle_search_in_law_rules
│ │ ├── func handle_rule_making
│ │ ├── func handle_chat_in_law
│ │ ├── func handle_qanon_title_repeat
│ │ ├── func handle_logical_chat_in_law
│ │ ├── func handle_conflict_qanon_asasi
│ │ ├── func handle_conflict_law_writing_policy
│ │ ├── func handle_subject_unities_to_evalution
│ │ ├── func show_stack_data
│ │ ├── func handle_summary_conflict_all_qavanin
│ │ ├── func save_to_db
│ │ └──
# input-flow
User-Input
app → initialize_webhook → Bale-Server
webhook
BaleBotCore
└→ BaleBotBase
└→ BaleBotUI
└→ StackManager
└→ UserManager
└→ Operation

View File

@ -1,4 +1,3 @@
elasticsearch==8.13.2
nltk
pydantic
fast-api
pydantic

View File

@ -1,7 +1,7 @@
# router.bale_bot.py
from fastapi import Depends, APIRouter, Request
import requests, traceback
from router.bale.bale_handle import BaleBot, BaleUpdate
from router.bale.bale_handle import BaleBotCore, BaleUpdate
from dependencies import _get_bale_token, _get_bale_bot
@ -20,7 +20,7 @@ chat_id
async def webhook(
request: Request,
token: str = Depends(_get_bale_token),
bale_bot: BaleBot = Depends(_get_bale_bot),
bale_bot: BaleBotCore = Depends(_get_bale_bot),
):
raw = await request.json()
# print(' webhook request ', raw)

View File

@ -1,11 +1,17 @@
BACK_BUTTON = {"text": "⬅️ مرحله قبل", "callback_data": "workflow_back"}
HOME_BUTTON = {"text": "🏠 خانه", "callback_data": "main"}
MORE_LIMIT_BUTTON = {"text": "بارگذاری نتایج بیشتر 10+", "callback_data": "more_limit"}
# MORE_EFFORT_BUTTON = {"text": "🧠 بررسی عمیق تر", "callback_data": "more_effort"}
MORE_EFFORT_BUTTON = {"text": "بررسی عمیق تر", "callback_data": "more_effort"}
from core.static import *
PREVIOUS_BUTTON = {"text": B_PREVIOUS, "callback_data": "previous_message"}
HOME_BUTTON = {"text": B_HOME, "callback_data": "main"}
MORE_LIMIT_BUTTON = {"text": B_10MORE, "callback_data": "more_limit"}
MORE_EFFORT_BUTTON = {"text": B_MORE_EFFORT, "callback_data": "more_effort"}
STOP_PROCCESS = {"text":B_STOP_PROCCESS, "callback_data":"main"}
BUTTON_TEXT_TO_CALLBACK_LIST = [
{"text": "جستجو"},
{"text": "گفتگو"},
{"text": "بازگشت به خانه"},
{"text": MC_JOST_JO},
{"text": MC_GOFT_GO},
{"text": MC_HOME},
]

File diff suppressed because it is too large Load Diff

View File

@ -4,34 +4,37 @@ from router.bale.bale_buttons import BUTTON_TEXT_TO_CALLBACK_LIST
import json
from typing import Optional, Callable, List, Any
from pydantic import BaseModel
from time import time
class SingleSearchData(BaseModel):
score:float
id:str
content:str
score: float
id: str
content: str
class BMNewSemanticSearchOutput(BaseModel):
query: str
result : List[SingleSearchData]
metadata : Dict
embed_model_time : float
cosine_similarity_time : float
rerank_time : float
result: List[SingleSearchData]
metadata: Dict
embed_model_time: float
cosine_similarity_time: float
rerank_time: float
class DbRule(BaseModel):
rule_id: str
rule_content: str
rule_type: str
section_id: str
section_content: str
section_full_path :str
section_full_path: str
qanon_id: str
qanon_etebar: str
qanon_title: str
state_etebar: str
class InputRule(BaseModel):
rule_id: str
rule_content: str
@ -39,12 +42,23 @@ class InputRule(BaseModel):
section_id: str
section_content: str
class SemanticSearchP2P(BaseModel):
in_rule: InputRule
db_rule: DbRule
score: float = 0
metadata: Dict
def __eq__(self, other):
return (
isinstance(other, RuleRelation)
and self.db_rule.section_id == other.db_rule.section_id
)
def __hash__(self):
return hash(self.db_rule.section_id)
class BaleStartMessageForm(BaseModel):
id: int
is_bot: bool = False
@ -181,6 +195,8 @@ class RelationIdentification(BaseModel):
"تعارض مستقر",
"بدون تعارض",
]
class Evaluation(BaseModel):
is_subject_unity_assessment_correct: bool
is_conflict_detection_correct: bool
@ -189,6 +205,7 @@ class Evaluation(BaseModel):
valid_relation_type: str
comments: str
class SingleRuleRelation(BaseModel):
rule_id: str
rule_content: str
@ -241,15 +258,58 @@ class RuleRelation(BaseModel):
# ----- relation-identification data
relation_identification: RelationIdentification | None = None
def __eq__(self, other):
return (
isinstance(other, RuleRelation)
and self.db_rule.section_id == other.db_rule.section_id
)
def __hash__(self):
return hash(self.db_rule.section_id)
class StateDetail(BaseModel):
state: str
state: str
message: str
button_text: str
end_buttons: List = []
inline_buttons: Optional[List[List[dict]]] = None
handler : str = None
allow_empty_input: bool = True
handler: str = None
allow_empty_input: bool = True
class BaleButton(BaseModel):
text: str
callback_data: str
class BaleMessage(BaseModel):
text: str
buttons: List[List[BaleButton]] = []
class PreviousMessage(BaseModel):
message: List | str
buttons: List[List[BaleButton]] = []
type: Literal["text", "chunked_text", "structured_text"]
class StackItem(BaseModel):
index: int
step_name: str
input_data: Any | int | None = (
None # اگر عدد بود یعنی داده از مرحله ایندکس قبلی امده
)
output_pure_data: Any
output_formed_data: Optional[PreviousMessage] = None
created_at: int = Field(default_factory=lambda: int(time()))
runtime_ms: float = -1
metadata: Dict[str, Any] = Field(default_factory=dict)
class BaleUser(BaseModel):
uc_id: str
@ -261,9 +321,10 @@ class BaleUser(BaseModel):
is_vip: bool = False
first_name: str = ""
last_name: str = ""
message_limit:int = 0
rule_relation: RuleRelation | None = None
subject_unities:Dict = {}
message_limit: int = 0
previous_message: PreviousMessage = None
rule_relation: RuleRelation | str | None = None
subject_unities: Dict = {}
# ---- defaults
effort: Literal["medium", "low"] = "low"
@ -271,11 +332,11 @@ class BaleUser(BaseModel):
permission: str = "normal"
# ---- runtime
is_processing_lock : bool = False
is_call_back_query : bool = False
state_detail : StateDetail = None
active_message_id : int = 0
is_processing_lock: bool = False
is_call_back_query: bool = False
state_detail: StateDetail = None
active_message_id: int = 0
input_query: str = "" # ورودی کاربر
last_input_query: str = "" # ورودی کاربر
call_back_query: str = "" # ورودی کاربر
@ -287,10 +348,7 @@ class BaleUser(BaseModel):
# ---- memory
last_query: Dict[str, str] = {} # آخرین سوال کاربر
last_result: Dict[str, Any] = {} # آخرین نتایج
last_runtime: Dict[str, Any] = (
{}
) # مثلا {"GP": {"effort": "medium", "limit": 20}} برای بقیه چیزها
stack: Dict[str, List] = {} # پشته برای داده های مرحله ای
stack: List[StackItem] = [] # پشته برای داده های مرحله ای
class KeyboardItem(BaseModel):
@ -322,8 +380,7 @@ class BalePayload(BaseModel):
class Step(BaseModel):
name: str
level : int
data_input : str
data_output : str
bot_output : List
level: int
data_input: str
data_output: str
bot_output: List

View File

@ -1,10 +1,6 @@
from router.bale.base_model import StateDetail
BUSY_TEXT = "⏳ درخواست قبلی شما در حال پردازش هست، لطفا تا اتمام آن منتظر بمانید ⏳"
from core.static import *
from router.bale.bale_buttons import *
class StateRegistry:
def __init__(self, states):
@ -17,7 +13,6 @@ class StateRegistry:
return list(self._states.values())
STATE = [
StateDetail(
state="search_in_law",
@ -68,12 +63,35 @@ STATE = [
message="""لطفا متن قانونی مورد نظر برای بررسی مغایرت با سیاست های کلی نظام را وارد کنید :""",
handler="handle_conflict_general_policy",
),
# StateDetail(
# state="choice_conflict_all_qavanin",
# button_text="بررسی مغایرت در تمام قوانین",
# end_buttons=[
# [{"text":B_CHOICE_SUMMARY,"callback_data":"summary_conflict_all_qavanin"}],
# [{"text":B_CHOICE_FULL,"callback_data":"full_conflict_all_qavanin"}],
# ],
# message=SM_CHOICE,
# ),
StateDetail(
state="conflict_all_qavanin",
state="subject_unities_to_evalution",
button_text="بررسی مغایرت مرحله اول",
end_buttons=[],
message="""""",
handler="handle_subject_unities_to_evalution",
),
StateDetail(
state="full_conflict_all_qavanin",
button_text="بررسی مغایرت در تمام قوانین",
end_buttons=[],
message="""لطفا متن قانونی مورد نظر برای بررسی مغایرت در تمام قوانین جمهوری اسلامی ایران را وارد کنید :""",
handler="handle_conflict_all_qavanin",
handler="handle_full_conflict_all_qavanin",
),
StateDetail(
state="summary_conflict_all_qavanin",
button_text="بررسی مغایرت در تمام قوانین",
end_buttons=[],
message="""لطفا متن قانونی مورد نظر برای بررسی مغایرت در تمام قوانین جمهوری اسلامی ایران را وارد کنید :""",
handler="handle_summary_conflict_all_qavanin",
),
StateDetail(
state="qanon_title_repeat",
@ -106,6 +124,12 @@ STATE = [
button_text="در دست توسعه",
message="""این قسمت در دست توسعه قرار دارد.""",
),
StateDetail(
state="previous_message",
button_text="",
message="",
handler='handle_previous_message'
),
StateDetail(
state="about_us",
button_text="درباره ما ⚡",
@ -118,8 +142,10 @@ STATE = [
),
]
STATE_REGISTERY = StateRegistry(STATE)
STATE_CONFIG = {i.state: i for i in STATE}
# MAIN_BUTTON = {i.state: i for i in STATE}
def build_buttons_form(button_form):
@ -132,16 +158,16 @@ def build_buttons_form(button_form):
if not state:
continue
row_buttons.append({
"text": state.button_text,
"callback_data": state.state
})
row_buttons.append(
{"text": state.button_text, "callback_data": state.state}
)
if row_buttons:
buttons.append(row_buttons)
return buttons
# Button-STYLE
main_button_form = [
["chat_in_law"],
@ -151,7 +177,7 @@ main_button_form = [
["conflict_law_writing_policy"],
["conflict_qanon_asasi"],
["conflict_general_policy"],
["conflict_all_qavanin"],
["contact_us", "about_us", "beta"]
["summary_conflict_all_qavanin"],
["contact_us", "about_us", "beta"],
]
MAIN_BUTTON = build_buttons_form(main_button_form)
MAIN_BUTTON = build_buttons_form(main_button_form)