Spaces:
Sleeping
Sleeping
import gradio as gr | |
import re | |
import inspect | |
import numpy as np | |
import pandas as pd | |
import os | |
from datetime import datetime | |
from sentence_transformers import SentenceTransformer | |
from sentence_transformers.util import cos_sim | |
from sentence_transformers import CrossEncoder | |
import mysql.connector | |
db_user = os.environ["DB_USER"] | |
mydb = mysql.connector.connect( | |
host=os.environ["DB_HOST"], | |
user=db_user, | |
password=os.environ["DB_PASSWORD"] | |
) | |
df_sample = pd.read_sql(f"SELECT * FROM {db_user}.mytable", mydb) | |
df_bobot = pd.read_sql(f"SELECT * FROM {db_user}.bobot", mydb) | |
df_bobot['BOBOT'] = [float(x.replace(",",".")) for x in df_bobot['BOBOT']]#.astype(float) | |
df_bobot["JENIS_KENDARAAN"] = [x[:-2] + x[-1] if x[-2] == "." else x for x in df_bobot["JENIS_KENDARAAN"]] | |
dict_swdkllj = { | |
"A":3000, | |
"B":23000, | |
"C1":35000, | |
"C2":83000, | |
"DP":35000, | |
"DU":73000, | |
"EP":153000, | |
"EU":90000, | |
"F":163000 | |
} | |
def find_swdkllj(row): | |
cc = int(row["jumlah_cc"]) | |
nm = str(row["nm_jenis_kb"]).upper() | |
if nm in ["AMBULANCE", "DAMKAR", "MOBIL JENAZAH"]: | |
return "A" | |
if nm in ["ALAT BERAT"]: | |
return "B" | |
if nm in ["SEDAN", "JEEP", "MINIBUS"]: | |
return "DP" | |
if "SPD. MOTOR" in nm: | |
if cc <= 50: | |
return "A" | |
elif cc <= 250: | |
return "C1" | |
else: | |
return "C2" | |
if "PICK UP" in nm: | |
if cc <= 2400: | |
return "DP" | |
df_sample["gol"] = df_sample.apply(find_swdkllj, axis=1) | |
df_sample["pnbp_stnk"] = df_sample["nm_jenis_kb"].apply( | |
lambda x: 100000 if x == "SPD. MOTOR R2" else 200000 | |
) | |
df_sample["pnbp_tnkb"] = df_sample["nm_jenis_kb"].apply( | |
lambda x: 60000 if x == "SPD. MOTOR R2" else 100000 | |
) | |
codes = """001 - Vehicle Registration (New) | |
002 - Vehicle Registration Renewal | |
003 - Vehicle Ownership Transfer | |
004 - Vehicle De-registration | |
005 - Lost Registration Certificate Replacement | |
006 - Address Change Update | |
007 - Vehicle Data Correction | |
008 - Ownership Name Correction | |
009 - Vehicle Tax Payment | |
010 - Late Payment Fee Processing | |
011 - Vehicle Type/Specification Update | |
012 - BBNKB (Transfer Fee of Vehicle Ownership) | |
013 - STNK Issuance (Vehicle Registration Certificate) | |
014 - STNK Renewal | |
015 - Motor Vehicle Roadworthiness Inspection | |
016 - Plate Number Renewal | |
017 - Lost Plate Replacement | |
018 - Vehicle Export Registration | |
019 - Vehicle Import Registration | |
020 - Fleet Vehicle Registration | |
021 - Bulk Vehicle Registration Update | |
022 - Vehicle Insurance Assistance | |
023 - Vehicle Accident Reporting | |
024 - Vehicle Usage Change Declaration (e.g., personal to commercial) | |
025 - Legal Document Verification | |
026 - Ownership Transfer for Inherited Vehicle | |
027 - STNK Temporary Suspension | |
028 - Proof of Ownership Document Update | |
029 - Vehicle Ownership History Check | |
030 - Vehicle Tax Recalculation Request | |
031 - Tax Exemption Application (for special cases) | |
032 - Deceased Owner’s Vehicle Ownership Transfer""".split("\n") | |
undetected = "099 - Other/Undetected" | |
# codes = """001 - Pendaftaran Kendaraan (Baru) | |
# 002 - Pembaruan Pendaftaran Kendaraan | |
# 003 - Alih Kepemilikan Kendaraan | |
# 004 - Pembatalan Pendaftaran Kendaraan | |
# 005 - Penggantian Sertifikat Pendaftaran Kendaraan yang Hilang | |
# 006 - Pembaruan Perubahan Alamat | |
# 007 - Koreksi Data Kendaraan | |
# 008 - Koreksi Nama Kepemilikan | |
# 009 - Pembayaran Pajak Kendaraan | |
# 010 - Proses Denda Keterlambatan Pembayaran | |
# 011 - Pembaruan Jenis/Spesifikasi Kendaraan | |
# 012 - Pembayaran Pajak Kendaraan Melalui E-Samsat | |
# 013 - Penerbitan STNK (Sertifikat Pendaftaran Kendaraan) | |
# 014 - Pembaruan STNK | |
# 015 - Pemeriksaan Kelayakan Jalan Kendaraan Bermotor | |
# 016 - Pembaruan Nomor Plat Kendaraan | |
# 017 - Penggantian Plat yang Hilang | |
# 018 - Pendaftaran Ekspor Kendaraan | |
# 019 - Pendaftaran Impor Kendaraan | |
# 020 - Pendaftaran Kendaraan Armada | |
# 021 - Pembaruan Pendaftaran Kendaraan Massal | |
# 022 - Bantuan Asuransi Kendaraan | |
# 023 - Pelaporan Kecelakaan Kendaraan | |
# 024 - Deklarasi Perubahan Penggunaan Kendaraan (misalnya, pribadi ke komersial) | |
# 025 - Verifikasi Dokumen Hukum | |
# 026 - Alih Kepemilikan Kendaraan Warisan | |
# 027 - Penangguhan Sementara STNK | |
# 028 - Pembaruan Dokumen Bukti Kepemilikan | |
# 029 - Pemeriksaan Riwayat Kepemilikan Kendaraan | |
# 030 - Permintaan Perhitungan Ulang Pajak Kendaraan | |
# 031 - Permohonan Pembebasan Pajak (untuk kasus khusus) | |
# 032 - Alih Kepemilikan Kendaraan Pemilik yang Meninggal""".split("\n") | |
codes = """001 - Pendaftaran Kendaraan | |
002 - Pembaruan Data Kendaraan | |
003 - Alih Kepemilikan atau Balik Nama Kendaraan | |
004 - Pelaporan Dokumen atau Plat yang Hilang | |
005 - Pembayaran dan Pengelolaan Pajak Kendaraan | |
006 - Pemeriksaan dan Verifikasi Kendaraan | |
007 - Pendaftaran Kendaraan Ekspor, Impor, atau Armada | |
008 - Pelaporan dan Bantuan Terkait Kendaraan | |
009 - Penangguhan atau Deklarasi Perubahan Penggunaan Kendaraan""".split("\n") | |
codes = """003 - Alih Kepemilikan atau Balik Nama Kendaraan | |
005 - Pembayaran dan Pengelolaan Pajak Kendaraan""".split("\n") | |
# documents = """Vehicle Registration | |
# Vehicle Data Update | |
# Vehicle Ownership or Change of Name | |
# Reporting of Lost Documents or Plates | |
# Vehicle Tax Payment and Management | |
# Vehicle Inspection and Verification | |
# Registration of Export, Import, or Fleet Vehicles | |
# Reporting and Assistence of Vehicles Insurance | |
# Suspension or Declaration of Change of Vehicle Use""".split("\n") | |
# examples = [ | |
# {"code": "001", "examples": [ | |
# "Register a new vehicle", | |
# "Vehicle registration application", | |
# "Apply for vehicle registration", | |
# "Submit new vehicle registration", | |
# "New vehicle registration request" | |
# ]}, | |
# {"code": "002", "examples": [ | |
# "Update vehicle information", | |
# "Change details of a registered vehicle", | |
# "Submit updated vehicle data", | |
# "Request vehicle data update", | |
# "Modify vehicle registration information" | |
# ]}, | |
# {"code": "003", "examples": [ | |
# "Transfer vehicle ownership", | |
# "Apply for vehicle name change", | |
# "Request ownership transfer for a vehicle", | |
# "Submit vehicle ownership change", | |
# "Process vehicle title transfer" | |
# ]}, | |
# {"code": "004", "examples": [ | |
# "Report lost vehicle documents (STNK, BPKB, etc)", | |
# "Declare missing license plates", | |
# "File a report for lost vehicle papers", | |
# "Lost vehicle documents reporting", | |
# "Inform authorities about missing vehicle documents" | |
# ]}, | |
# {"code": "005", "examples": [ | |
# "Pay vehicle tax", | |
# "Manage vehicle tax payments", | |
# "Submit vehicle tax payment", | |
# "Request vehicle tax management services", | |
# "Complete annual vehicle tax" | |
# ]}, | |
# {"code": "006", "examples": [ | |
# "Conduct vehicle inspection", | |
# "Request vehicle verification check", | |
# "Submit vehicle for verification", | |
# "Schedule vehicle examination", | |
# "Apply for vehicle inspection and verification" | |
# ]}, | |
# {"code": "007", "examples": [ | |
# "Register an imported vehicle", | |
# "Submit registration for export vehicle", | |
# "Apply for fleet vehicle registration", | |
# "Register new vehicle for export or import", | |
# "Fleet vehicle registration application" | |
# ]}, | |
# {"code": "008", "examples": [ | |
# "Report vehicle-related issues", | |
# "Request assistance for a vehicle problem", | |
# "Submit report concerning a vehicle", | |
# "File for vehicle-related support", | |
# "Seek help with vehicle concerns" | |
# ]}, | |
# {"code": "009", "examples": [ | |
# "Suspend vehicle usage", | |
# "Declare change of vehicle usage purpose", | |
# "Request a hold on vehicle usage", | |
# "Submit application for vehicle usage change", | |
# "File for suspension of vehicle operations" | |
# ]} | |
# ] | |
examples = [ | |
{"code": "001", "examples": [ | |
"Daftarkan kendaraan baru", | |
"Pengajuan pendaftaran kendaraan", | |
"Ajukan pendaftaran kendaraan", | |
"Serahkan pendaftaran kendaraan baru", | |
"Permintaan pendaftaran kendaraan baru" | |
]}, | |
{"code": "002", "examples": [ | |
"Perbarui informasi kendaraan", | |
"Ubah detail kendaraan yang terdaftar", | |
"Ajukan pembaruan data kendaraan", | |
"Permintaan pembaruan data kendaraan", | |
"Modifikasi informasi pendaftaran kendaraan" | |
]}, | |
{"code": "003", "examples": [ | |
"Alihkan kepemilikan kendaraan", | |
"Ajukan perubahan nama kendaraan", | |
"Permintaan pengalihan kepemilikan kendaraan", | |
"Serahkan perubahan kepemilikan kendaraan", | |
"Proses alih nama kendaraan" | |
]}, | |
{"code": "004", "examples": [ | |
"Laporkan dokumen kendaraan hilang (STNK, BPKB, dll)", | |
"Nyatakan plat nomor hilang", | |
"Ajukan laporan dokumen kendaraan hilang", | |
"Pelaporan dokumen kendaraan yang hilang", | |
"Informasikan pihak berwenang tentang dokumen kendaraan yang hilang" | |
]}, | |
{"code": "005", "examples": [ | |
"Bayar pajak kendaraan", | |
"Kelola pembayaran pajak kendaraan", | |
"Ajukan pembayaran pajak kendaraan", | |
"Permintaan layanan manajemen pajak kendaraan", | |
"Selesaikan pajak tahunan kendaraan" | |
]}, | |
{"code": "006", "examples": [ | |
"Lakukan pemeriksaan kendaraan", | |
"Ajukan pemeriksaan verifikasi kendaraan", | |
"Serahkan kendaraan untuk verifikasi", | |
"Jadwalkan pemeriksaan kendaraan", | |
"Ajukan inspeksi dan verifikasi kendaraan" | |
]}, | |
{"code": "007", "examples": [ | |
"Daftarkan kendaraan impor", | |
"Ajukan pendaftaran kendaraan ekspor", | |
"Ajukan pendaftaran kendaraan armada", | |
"Daftarkan kendaraan baru untuk ekspor atau impor", | |
"Pengajuan pendaftaran kendaraan armada" | |
]}, | |
{"code": "008", "examples": [ | |
"Laporkan masalah terkait kendaraan", | |
"Permintaan bantuan untuk masalah kendaraan", | |
"Ajukan laporan mengenai kendaraan", | |
"Ajukan dukungan terkait kendaraan", | |
"Cari bantuan terkait permasalahan kendaraan" | |
]}, | |
{"code": "009", "examples": [ | |
"Tangguhkan penggunaan kendaraan", | |
"Nyatakan perubahan tujuan penggunaan kendaraan", | |
"Ajukan penangguhan penggunaan kendaraan", | |
"Ajukan perubahan penggunaan kendaraan", | |
"Ajukan penangguhan operasional kendaraan" | |
]} | |
] | |
# examples = [ | |
# {"code": "001", "examples": [ | |
# codes[0][6:], | |
# "Pendaftaran kendaraan", | |
# "Daftar baru untuk plat kendaraan", | |
# "Registrasi kendaraan" | |
# ]}, | |
# {"code": "002", "examples": [ | |
# codes[1][6:], | |
# "Perubahan alamat, warna, komponnen kendaraan", | |
# "Update informasi kendaraan", | |
# "Perubahan data pemilik", | |
# ]}, | |
# {"code": "003", "examples": [ | |
# codes[2][6:], | |
# "Alih kepemilikan kendaraan", | |
# "Balik nama untuk kendaraan", | |
# "Perubahan pemilik pada kendaraan" | |
# ]}, | |
# {"code": "004", "examples": [ | |
# codes[3][6:], | |
# "Laporan kehilangan dokumen kendaraan", | |
# "Hilangnya plat nomor kendaraan", | |
# "Dokumen kendaraan dilaporkan hilang" | |
# ]}, | |
# {"code": "005", "examples": [ | |
# codes[4][6:], | |
# "Pembayaran pajak kendaraan", | |
# "Kelola pajak tahunan kendaraan", | |
# "Pajak kendaraan" | |
# ]}, | |
# {"code": "006", "examples": [ | |
# codes[5][6:], | |
# "Pemeriksaan fisik kendaraan", | |
# "Verifikasi kendaraan", | |
# "Cek kondisi kendaraan" | |
# ]}, | |
# {"code": "007", "examples": [ | |
# codes[6][6:], | |
# "Pendaftaran kendaraan impor", | |
# "Registrasi armada baru", | |
# "Kendaraan ekspor didaftarkan" | |
# ]}, | |
# {"code": "008", "examples": [ | |
# codes[7][6:], | |
# "Pelaporan terkait kendaraan", | |
# "Bantuan atau Asuransi atas kendaraan", | |
# "Laporkan masalah kendaraan" | |
# ]}, | |
# {"code": "009", "examples": [ | |
# codes[8][6:], | |
# "Penangguhan penggunaan kendaraan", | |
# "Deklarasi perubahan fungsi kendaraan", | |
# "Penggunaan baru untuk kendaraan" | |
# ]} | |
# ] | |
vehicle_tax_info = { | |
"B 1234 BCA": { | |
"no_rangka": "1237191234", | |
"type": "SUV", | |
"tanggal": "23 Desember 2024", | |
"status": "Belum Bayar", | |
"harga_jual": 500_000_000 # In Rupiah | |
}, | |
"B 5678 XYZ": { | |
"no_rangka": "9876543210", | |
"type": "Sedan", | |
"tanggal": "15 Januari 2025", | |
"status": "Belum Bayar", | |
"harga_jual": 375_800_000 # In Rupiah | |
}, | |
"D 3456 DEF": { | |
"no_rangka": "4561237890", | |
"type": "MPV", | |
"tanggal": "10 Februari 2025", | |
"status": "Sudah Bayar", | |
"harga_jual": 400_000_000 # In Rupiah | |
} | |
} | |
# Table for detail calculations (perhitungan) | |
detail_perhitungan = { | |
"001": { | |
"name": "Pendaftaran Kendaraan", | |
"formula": lambda harga_jual: harga_jual * 0.1, | |
# Example formula: 10% of harga_jual | |
}, | |
"002": { | |
"name": "Pembaruan Data Kendaraan", | |
"formula": lambda harga_jual: harga_jual * 0.05, | |
# Example formula: 5% of harga_jual | |
}, | |
"003": { | |
"name": "Alih Kepemilikan (Balik Nama) Kendaraan", | |
"formula": lambda harga_jual: harga_jual * 0.1, | |
# Example formula: 10% of harga_jual | |
}, | |
"004": { | |
"name": "Penggantian Dokumen atau Plat yang Hilang", | |
"formula": lambda harga_jual: harga_jual * 0.03, | |
# Example formula: 3% of harga_jual | |
}, | |
"005": { | |
"name": "Pembayaran dan Pengelolaan Pajak Kendaraan", | |
"formula": lambda harga_jual: harga_jual * 0.12, | |
# Example formula: 12% of harga_jual | |
}, | |
"006": { | |
"name": "Pemeriksaan dan Verifikasi Kendaraan", | |
"formula": lambda harga_jual: 100000, | |
# Example formula: 2% of harga_jual | |
}, | |
"007": { | |
"name": "Pendaftaran Kendaraan Ekspor, Impor, atau Armada", | |
"formula": lambda harga_jual: harga_jual * 0.15, | |
# Example formula: 15% of harga_jual | |
}, | |
"008": { | |
"name": "Pelaporan dan Bantuan Terkait Kendaraan", | |
"formula": lambda harga_jual: harga_jual * 0.04, | |
# Example formula: 4% of harga_jual | |
}, | |
"009": { | |
"name": "Penangguhan atau Deklarasi Perubahan Penggunaan Kendaraan", | |
"formula": lambda harga_jual: harga_jual * 0.06, | |
# Example formula: 6% of harga_jual | |
} | |
} | |
undetected = "099 - Lainnya/Tidak Terdeteksi" | |
model_ids = [ | |
"BAAI/bge-m3", | |
"sentence-transformers/paraphrase-multilingual-mpnet-base-v2", | |
"intfloat/multilingual-e5-small", | |
"sentence-transformers/distiluse-base-multilingual-cased-v2", | |
"Alibaba-NLP/gte-multilingual-base", | |
"sentence-transformers/paraphrase-multilingual-MiniLM-L12-v2", | |
"jinaai/jina-reranker-v2-base-multilingual", | |
"BAAI/bge-reranker-v2-m3", | |
] | |
# model_id = "sentence-transformers/paraphrase-multilingual-MiniLM-L12-v2" | |
# model_id = "Alibaba-NLP/gte-multilingual-base" | |
# model_id = "BAAI/bge-m3" | |
# model_id = "sentence-transformers/paraphrase-multilingual-mpnet-base-v2" | |
# model_id = "intfloat/multilingual-e5-small" | |
# model_id = "sentence-transformers/distiluse-base-multilingual-cased-v2" | |
model_id = model_ids[-1] | |
model = None | |
codes_emb = None | |
def load_model(model_id): | |
# global model | |
# global codes_emb | |
if model_id in model_ids[-2:]: | |
model = CrossEncoder( | |
# "jinaai/jina-reranker-v2-base-multilingual", | |
# "BAAI/bge-reranker-v2-m3", | |
model_id, | |
automodel_args={"torch_dtype": "auto"}, | |
trust_remote_code=True, | |
) | |
return model, None | |
else: | |
model = SentenceTransformer(model_id, trust_remote_code=True) | |
codes_emb = model.encode([x[6:] for x in codes]) | |
# codes_emb = model.encode([x["examples"] for x in examples])#.mean(axis=1) | |
# codes_emb = np.mean([model.encode(x["examples"]) for x in examples], axis=1) | |
return model, codes_emb | |
model, codes_emb = load_model(model_id) | |
# for x in examples: | |
# codes_emb.append(model.encode(x["examples"])) | |
# codes_emb = np.mean(codes_emb, axis=1) | |
def censor_middle(number, num_to_hide=4): | |
number_str = str(number) | |
if num_to_hide == -1: | |
num_to_hide = int(len(number_str)*0.8) | |
middle_index = len(number_str) // 2 | |
start_index = middle_index - num_to_hide // 2 | |
end_index = middle_index + num_to_hide // 2 | |
censored_part = "\*" * num_to_hide | |
censored_number = number_str[:start_index] + censored_part + number_str[end_index:] | |
return censored_number | |
def get_calculation(request_code, plate_number): | |
print(request_code, plate_number, "GET CALC") | |
calc = detail_perhitungan.get(request_code) | |
vehicle = vehicle_tax_info.get(plate_number) | |
if vehicle != None and calc != None: | |
harga_jual = vehicle.get("harga_jual") | |
formula = calc.get("formula") | |
result = formula(harga_jual) | |
description = inspect.getsource(formula).split(":", 2)[-1].strip() | |
result_detail = request_code + " - " + calc.get("name") | |
return result, str(description), result_detail | |
elif calc != None: | |
formula = calc.get("formula") | |
description = inspect.getsource(formula).split(":", 2)[-1].strip() | |
result_detail = request_code + " - " + calc.get("name") | |
return None, str(description), result_detail | |
else: | |
return None, None, None | |
def build_output_formula(descriptions, result_details): | |
out = "----------------------------------------------------\n\n" | |
out = "Daftar Kode Permohonan:\n" | |
for i, (desc,detail) in enumerate(zip(descriptions, result_details)): | |
# harga_jual = str(vehicle.get("harga_jual")) | |
out += f"{i+1}. {detail}\nRumus: {desc}\n" | |
return out | |
def build_output_vehicle(plate_number): | |
vehicle = vehicle_tax_info.get(plate_number).copy() | |
out = "----------------------------------------------------\n\n" | |
out = "Nomor Polisi: " + plate_number + "\n" | |
vehicle["no_rangka"] = censor_middle(vehicle["no_rangka"]) | |
vehicle["harga_jual"] = "Rp{:,}".format(vehicle["harga_jual"]) | |
out += "\n".join([k + " : " + str(v) for k,v in vehicle.items()]) | |
return out | |
def build_output(result, description, result_detail, plate_number): | |
return build_outputs([result], [description], [result_detail], plate_number) | |
def build_outputs(results, descriptions, result_details, plate_number): | |
vehicle = vehicle_tax_info.get(plate_number).copy() | |
vehicle["harga_jual"] = "Rp{:,}".format(vehicle["harga_jual"]) | |
out = "----------------------------------------------------\n\n" | |
out = "Nomor Polisi: " + plate_number + "\n" | |
out += "\n".join([k + " : " + str(v) if k != "no_rangka" else k + " : " + censor_middle(v) for k,v in vehicle.items()]) | |
# out += "\n----------------------------------------------" | |
# out += f"\nWajib Pajak dengan NoPol {plate_number} ingin melakukan proses berikut:\n" | |
out += "\n\nDaftar Kode Permohonan:\n" | |
for i, (res,desc,detail) in enumerate(zip(results, descriptions, result_details)): | |
harga_jual = vehicle["harga_jual"] | |
res_str = "{:,}".format(res) | |
out += f"{i+1}. {detail}\nRumus: {desc}\nDetail perhitungan: {desc.replace('harga_jual', harga_jual)} = Rp{res_str}\n" | |
# out += "----------------------------\nEstimasi biaya: " | |
out += "\n\n\nEstimasi Biaya: " | |
if len(results) > 1: | |
out += " + ".join(["Rp{:,}".format(x) for x in results]) | |
out += " = Rp{:,}".format(sum(results)) | |
else: | |
out += "Rp{:,}".format(results[0]) | |
out += "\n\n----------------------------" | |
# out += "\n----------------------------\n\n--------------------------------" | |
return out | |
def respond( | |
message, | |
history: list[tuple[str, str]], | |
threshold, | |
is_multiple, | |
n_num, | |
): | |
global codes_emb | |
global undetected | |
undetected_code = undetected[:3] | |
# if history and history[-1][-1][21:24] == undetected_code: | |
# list_his = "" | |
# for his in history[::-1]: | |
# if his[-1][21:24] != undetected_code: | |
# break | |
# list_his = his[0] + "\n" + list_his | |
# message += "\n" + list_his | |
# pattern = r'\b([A-Z]{1,2})\s?(\d{4})\s?([A-Z]{3})\b' | |
# pattern = r'\b([A-Z]{1,2})\s?(\d{4})\s?([A-Z]{1,3})\b' | |
pattern = r'\b([A-Za-z]{1,2})\s?(\d{4})\s?([A-Za-z]{1,3})\b' | |
matches = re.findall(pattern, message) | |
plates = [" ".join(x).upper() for i,x in enumerate(matches)] | |
plate_numbers = ", ".join(plates) | |
# if model.config._name_or_path in model_ids[-2:]: | |
if type(model) == CrossEncoder: | |
# documents = [v["name"] for v in detail_perhitungan.values()] | |
sentence_pairs = [[message, v["name"]] for v in detail_perhitungan.values()] | |
# sentence_pairs = [[message, doc] for doc in documents] | |
scores = model.predict(sentence_pairs, convert_to_tensor=True) | |
weights = [1,1,1,1,1,1,1,1,1] | |
# scores = [x["score"] for x in model.rank(message, documents)] | |
else: | |
text_emb = model.encode(message) | |
scores = cos_sim(codes_emb, text_emb).mean(axis=-1)#[:,0] | |
weights = [19,8,7,6,5,4,3,2,1] | |
scores_argsort = scores.argsort(descending=True) | |
# if n_num == 0: | |
# std = scores.std() | |
# else: | |
# std = 0 | |
if n_num == 0: | |
# w_avg = np.average(scores[scores_argsort].numpy(), weights=range(len(scores),0,-1)) | |
w_avg = np.average(scores[scores_argsort].numpy(), weights=weights) | |
else: | |
w_avg = 9999 | |
#[::-1] | |
if is_multiple: | |
request_details = [] | |
request_numbers = [] | |
request_scores = [] | |
# request_undetected = False | |
# for i,score in enumerate(scores): | |
if scores[scores_argsort[0]] < threshold: | |
request_details.append(undetected[6:]) | |
request_numbers.append(undetected_code) | |
else: | |
for i in scores_argsort: | |
# if scores[scores_argsort[0]] - std <= scores[i]: | |
if scores[i] > w_avg: | |
request_details.append(codes[i][6:]) | |
request_numbers.append(codes[i][:3]) | |
request_scores.append(str( round(scores[i].tolist(), 3) ) ) | |
else: | |
if len(request_scores) >= n_num: | |
break | |
if scores[i] > threshold: | |
request_details.append(codes[i][6:]) | |
request_numbers.append(codes[i][:3]) | |
request_scores.append(str( round(scores[i].tolist(), 3) ) ) | |
request_numbers_copy = request_numbers | |
request_details_copy = request_details | |
request_numbers = "\n".join(request_numbers) | |
request_details = "\n".join(request_details) | |
request_scores = "\n".join(request_scores) | |
# if len(request_numbers_copy) > 0: | |
# for code, detail in zip(request_numbers_copy, request_details_copy): | |
# kode_mohon = detail_perhitungan.get(code) | |
# formula = kode_mohon.get("formula") | |
# description = inspect.getsource(formula).split(":", 2)[-1].strip() | |
# if request_undetected and len(plates) == 0: | |
# + f"\n\nConfidence score:\n{request_scores}" | |
# return "Request code number:\n" + request_numbers + "\n\nRequest detail:\n" + request_details + "\n\nPlate numbers: " + plate_numbers | |
print(request_scores) | |
out = "" | |
for plate in plates: | |
results, descriptions, result_details = [], [], [] | |
for code in request_numbers_copy: | |
result, description, result_detail = get_calculation(code, plate) | |
if result != None: | |
results.append(result) | |
if descriptions != None: | |
descriptions.append(description) | |
result_details.append(result_detail) | |
if results: | |
out += "\n\n" + build_outputs(results, descriptions, result_details, plate) | |
elif vehicle_tax_info.get(plate): | |
out += "\n\n" + build_output_vehicle(plate) | |
if out == "": | |
descriptions, result_details = [], [] | |
for code in request_numbers_copy: | |
result, description, result_detail = get_calculation(code, "") | |
if description != None: | |
descriptions.append(description) | |
result_details.append(result_detail) | |
if descriptions: | |
out += "\n\n" + build_output_formula(descriptions, result_details) | |
else: | |
return "Request code number: " + request_numbers + "\nRequest detail: " + request_details + "\nPlate numbers: " + plate_numbers | |
return out | |
# result, description, result_detailget_calculation(request_code, plate_number) | |
s_max = scores.argmax() | |
if scores[s_max] < threshold: | |
# request_code = "033 - Other/Undetected" | |
request_code = undetected | |
else: | |
request_code = codes[scores.argmax()] | |
# "{:.2f}".format(a) | |
# out = "Request code number: " + request_code[:3] + "\nRequest detail: " + request_code[6:] + f"\nConfidence score: {round(scores[s_max].tolist(),3)}" + "\nPlate numbers: " + plate_numbers | |
out = "" | |
for plate in plates: | |
results, descriptions, result_details = [], [], [] | |
result, description, result_detail = get_calculation(request_code[:3], plate) | |
if result != None: | |
results.append(result) | |
descriptions.append(description) | |
result_details.append(result_detail) | |
out += "\n\n" + build_outputs(results, descriptions, result_details, plate) | |
elif vehicle_tax_info.get(plate): | |
out += "\n\n" + build_output_vehicle(plate) | |
elif description != None: | |
descriptions.append(description) | |
result_details.append(result_detail) | |
out += "\n\n" + build_output_formula(descriptions, result_details) | |
# else: | |
# # + f"\nConfidence score: {round(scores[s_max].tolist(),3)}" | |
# out += "Request code number: " + request_code[:3] + "\nRequest detail: " + "\nPlate numbers: " + plate_numbers | |
if out == "": | |
if request_code[:3] == undetected_code: | |
return "Request code number: " + request_code[:3] + "\nRequest detail: " + request_code[6:] + "\nPlate numbers: " + plate_numbers | |
else: | |
result, description, result_detail = get_calculation(request_code[:3], "") | |
out += build_output_formula([description], [result_detail]) | |
return out | |
# if vehicle_tax_info.get(request_detail) | |
# for val in history: | |
# if val[0]: | |
# messages.append({"role": "user", "content": val[0]}) | |
# if val[1]: | |
# messages.append({"role": "assistant", "content": val[1]}) | |
# messages.append({"role": "user", "content": message}) | |
# response = "" | |
# for message in client.chat_completion( | |
# messages, | |
# max_tokens=max_tokens, | |
# stream=True, | |
# temperature=temperature, | |
# top_p=top_p, | |
# ): | |
# token = message.choices[0].delta.content | |
# response += token | |
# yield response | |
""" | |
For information on how to customize the ChatInterface, peruse the gradio docs: https://www.gradio.app/docs/chatinterface | |
""" | |
# demo = gr.ChatInterface( | |
# respond, | |
# ) | |
def reload(chosen_model_id): | |
global model | |
global model_id | |
global codes_emb | |
if chosen_model_id != model_id: | |
model, codes_emb = load_model(chosen_model_id) | |
# model = SentenceTransformer(chosen_model_id, trust_remote_code=True) | |
# model_id = chosen_model_id | |
# codes_emb = model.encode([x[6:] for x in codes]) | |
# codes_emb = model.encode([x["examples"] for x in examples])#.mean(axis=1) | |
# codes_emb = np.mean([model.encode(x["examples"]) for x in examples], axis=1) | |
return f"Model {chosen_model_id} has been succesfully loaded!" | |
return f"Model {chosen_model_id} is ready!" | |
def respond_pkb( | |
message, | |
history: list[tuple[str, str]], | |
threshold, | |
tarif_pkb, | |
tarif_bbnkb, | |
): | |
global codes_emb | |
global undetected | |
undetected_code = undetected[:3] | |
# tarif_pkb = 1.5/100 | |
# tarif_bbnkb = 0.1 | |
pattern = r'\b([A-Za-z]{1,2})\s?(\d{2,4})\s?([A-Za-z]{1,3})\b' | |
matches = re.findall(pattern, message) | |
plates = [" ".join(x).upper() for i,x in enumerate(matches)] | |
if type(model) == CrossEncoder: | |
sentence_pairs = [[message, v[6:]] for v in codes] | |
scores = model.predict(sentence_pairs, convert_to_tensor=True) | |
weights = [9,8] | |
else: | |
text_emb = model.encode(message) | |
scores = cos_sim(codes_emb, text_emb).mean(axis=-1)#[:,0] | |
weights = [11,9] | |
scores_argsort = scores.argsort(descending=True) | |
w_avg = np.average(scores[scores_argsort].numpy(), weights=weights) | |
out = "" | |
for inp in plates: | |
vehicle = df_sample[df_sample["no_polisi"] == inp.strip()].copy() | |
if vehicle.shape[0] == 0: | |
out += f"\n\n---\nKendaraan {inp} Tidak Ditemukan\n" | |
else: | |
vehicle["nm_pemilik"] = censor_middle(vehicle["nm_pemilik"].values[0], -1) | |
vehicle["al_pemilik"] = censor_middle(vehicle["al_pemilik"].values[0], -1) | |
v_type = vehicle["nm_jenis_kb"].values[0] | |
nilai_jual = vehicle["nilai_jual"].values[0] | |
pnbp_stnk = vehicle["pnbp_stnk"].values[0] | |
pnbp_tnkb = vehicle["pnbp_tnkb"].values[0] | |
bobot = df_bobot[df_bobot["JENIS_KENDARAAN"]==v_type]["BOBOT"].values[0] | |
bbnkb = tarif_bbnkb * nilai_jual * 1 # pengenaan | |
pkb = tarif_pkb * bobot * nilai_jual * 1 # pengenaan | |
vehicle["nilai_jual"] = f"Rp{int(nilai_jual):,}" | |
out += "\n\n---\nDetail Kendaraan:" | |
for k,v in vehicle.iloc[0].items(): | |
out += f"\n{k} \t\t: {v}" | |
# out += "\n==================================================================" | |
out += "\n--" | |
if scores[scores_argsort[0]] < threshold: | |
continue | |
header_rincian = "| POKOK | DENDA | TOTAL ||\n|-:|-:|-:|:-|\n" | |
rincian = "\n\n### RINCIAN:\n\n" + header_rincian | |
is_rincian = False | |
out_k = "" | |
if scores[0] > w_avg: | |
out += f"\nBBNKB \t\t: {int(bbnkb):,}" | |
out_k += "\nRumus Bea Balik Nama Kendaraan Bermotor (BBNKB) : TARIF x NJKB x PENGENAAN" | |
out_k += f"\nKalkulasi : {tarif_bbnkb*100}% x Rp{int(nilai_jual):,} x 100%" | |
out_k += f"\nTotal Pembayaran : Rp{int(bbnkb):,}\n" | |
rincian += f"|{int(bbnkb):,}|0|{int(bbnkb):,}|BBNKB|\n" | |
is_rincian = True | |
else: | |
bbnkb = 0 | |
if scores[1] > w_avg: | |
d = datetime.now().date() - vehicle["tg_akhir_pkb"].values[0] | |
d = d.days // 365 | |
if d < 1: | |
d = 1 | |
# swdkllj = 35000 | |
swdkllj = dict_swdkllj.get(vehicle["gol"].values[0]) | |
out += f"\nPKB \t\t: {int(pkb*d):,}" | |
out += f"\nSWDKLLJ \t\t: {int(swdkllj*d):,}" | |
out += f"\nPNBP STNK \t\t:{int(pnbp_stnk):,}" | |
out += f"\nPNBP TNKB \t\t:{int(pnbp_tnkb):,}" | |
out += f"\nTOTAL \t\t: {int(pkb*d + swdkllj*d + pnbp_stnk + pnbp_tnkb + bbnkb):,}" | |
out_k += "\nRumus Pokok Pajak Kendaraan Bermotor (PKB) : TARIF * NJKB * BOBOT * PENGENAAN * TAHUN BAYAR" | |
out_k += f"\nKalkulasi : {tarif_pkb*100}% * Rp{int(nilai_jual):,} * {bobot} * 100% * {d}" | |
out_k += f"\nTotal Pembayaran : Rp{int(pkb*d):,}\n" | |
out_k += "\nRumus Total PKB: PKB + SWDKLLJ + PNBP STNK + PNBP TNKB" | |
out_k += f"\nKalkulasi : Rp{int(pkb*d):,} + Rp{int(swdkllj*d):,} + Rp{int(pnbp_stnk):,} + Rp{int(pnbp_tnkb):,}" | |
out_k += f"\nTotal Pembayaran : Rp{int(pkb*d + swdkllj*d + pnbp_stnk + pnbp_tnkb):,}\n" | |
rincian += f"|{int(pkb*d):,}|0|{int(pkb*d):,}|PKB|\n" + f"|{int(swdkllj*d):,}|0|{int(swdkllj*d):,}|SWDKLLJ|\n\n" | |
rincian_pkb = "### RINCIAN PKB:\n\n| POKOK | DENDA | TOTAL |\n|-:|-:|-:|\n" | |
rincian_swdkllj = "### RINCIAN SWDKLLJ:\n\n| POKOK | DENDA | TOTAL |\n|-:|-:|-:|\n" | |
for i in range(d): | |
rincian_pkb += f"|{int(pkb):,}|0|{int(pkb):,}|PKB|\n" | |
rincian_swdkllj += f"|{int(swdkllj):,}|0|{int(swdkllj):,}|PKB|\n" | |
rincian += rincian_pkb + "\n" + rincian_swdkllj | |
is_rincian = True | |
out += out_k | |
if is_rincian: | |
out += rincian | |
if not out and scores[scores_argsort[0]] >= threshold: | |
if scores[0] > w_avg: | |
out += "\nRumus Bea Balik Nama Kendaraan Bermotor (BBNKB) : TARIF x NJKB x PENGENAAN" | |
if scores[1] > w_avg: | |
out += "\nRumus Pokok Pajak Kendaraan Bermotor (PKB) : TARIF * NJKB * BOBOT * PENGENAAN" | |
return out | |
with gr.Blocks() as demo: | |
# Add header title and description | |
gr.Markdown("# List of Request Numbers") | |
gr.Markdown("<br>".join(codes) + "<br>" + undetected) | |
gr.Markdown("# Valid License Plate Number Criteria:") | |
gr.Markdown("(1-2 letters) (4 numbers) (1-3 letters)") | |
# gr.Markdown("# Example Valid Plate Numbers") | |
# gr.Markdown("<br>".join(vehicle_tax_info.keys())) | |
gr.Markdown("# Example Valid Plate Numbers") | |
gr.Dataframe(df_sample.drop_duplicates(['nm_jenis_kb'])) | |
gr.Markdown("# Choose & Load Model:") | |
reload_model = gr.Interface( | |
fn=reload, | |
inputs=[gr.Dropdown(choices=model_ids, value=model_id)], | |
outputs="text", | |
# gr.HighlightedText( | |
# label="status", | |
# combine_adjacent=True, | |
# show_legend=True, | |
# color_map={"+": "red", "-": "green"} | |
# ), | |
) | |
gr.Markdown("# Chatbot Interface:") | |
chat_interface = gr.ChatInterface( | |
respond_pkb, | |
chatbot=gr.Chatbot(height=670),#800 | |
additional_inputs=[ | |
gr.Number(0.0005, label="confidence threshold", show_label=True, minimum=0., maximum=1.0, step=0.1), | |
gr.Number(0.015, label="tarif pajak kendaraan bermotor (pkb)", show_label=True, minimum=0., maximum=1.0, step=0.01), | |
gr.Number(0.1, label="tarif bea balik nama kendaraan bermotor (bbnkb)", show_label=True, minimum=0., maximum=1.0, step=0.05), | |
# gr.Checkbox(True, label="multiple", info="Allow multiple request code numbers"), | |
# gr.Number(3, label="maximum number of request codes", show_label=True, minimum=0, step=1, precision=0) | |
], | |
# # type="messages", | |
# # textbox=gr.Textbox(placeholder="Ask me a yes or no question", container=False, scale=7), | |
# # title="SamSat Virtual Assistant", | |
# # description="Ask Yes Man any question", | |
# # theme="soft", | |
# # examples=["balik nama D 3456 DEF", "bayar pajak B 1234 BCA", "halo, selamat pagi!"], | |
# # cache_examples=True, | |
) | |
if __name__ == "__main__": | |
demo.launch() | |