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("
".join(codes) + "
" + 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("
".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()