Ringkas-In / src /core /action_extractor.py
anthonysigid's picture
deploy SummAIrizer apps to spaces
2a16478
Raw
History Blame Contribute Delete
3.88 kB
import re
from typing import List, Dict
class ActionItemExtractor:
def __init__(self):
"""
Inisialisasi Action Item Extractor.
Untuk baseline, menggunakan pendekatan berbasis aturan (Rule-based / Regex)
yang difokuskan pada pola kalimat bahasa Indonesia untuk mengidentifikasi
tugas, PIC (Person in Charge), dan deadline.
Dalam versi Advanced, modul ini sebaiknya diganti dengan panggilan ke LLM
(OpenAI/Gemini) menggunakan prompt spesifik.
"""
# Pola-pola umum yang mengindikasikan action item
self.task_indicators = [
r"harus\s+([a-zA-Z0-9\s]+)",
r"bertanggung\s+jawab\s+(?:untuk|pada)?\s*([a-zA-Z0-9\s]+)",
r"ditugaskan\s+(?:untuk)?\s*([a-zA-Z0-9\s]+)",
r"wajib\s+([a-zA-Z0-9\s]+)"
]
# Pola untuk mencari entitas penanggung jawab (huruf kapital di awal kalimat atau sebelum indikator)
# Sederhananya, mencari Kata Ganti atau Nama Orang di sekitar kata tugas
self.pic_pattern = r"([A-Z][a-z]+(?:\s+[A-Z][a-z]+)*)"
# Pola untuk mencari deadline
self.deadline_indicators = [
r"paling\s+lambat\s+([a-zA-Z0-9\s]+)",
r"sebelum\s+(?:hari|tanggal)?\s*([a-zA-Z0-9\s]+)",
r"maksimal\s+(?:tanggal)?\s*([a-zA-Z0-9\s]+)"
]
def extract_action_items(self, text: str) -> List[str]:
"""
Mengekstrak action items dari teks.
Format output yang diharapkan: "[PIC] -> [Tugas] -> [Deadline]"
"""
if not text:
return []
action_items = []
# Split teks menjadi kalimat-kalimat
sentences = re.split(r'(?<=[.!?])\s+', text)
for sentence in sentences:
sentence = sentence.strip()
if not sentence:
continue
task = None
pic = "Unknown"
deadline = "No Deadline"
# 1. Cari indikator tugas
for pattern in self.task_indicators:
match = re.search(pattern, sentence, re.IGNORECASE)
if match:
# Ambil teks setelah indikator tugas sampai koma atau titik
task_raw = match.group(1).split(',')[0].split('.')[0].strip()
# Buang kata "sebelum", "paling lambat", dll dari task
task = re.split(r'\b(sebelum|paling lambat|maksimal)\b', task_raw, flags=re.IGNORECASE)[0].strip()
break
# Jika ada tugas yang ditemukan
if task:
# 2. Cari PIC (siapa yang harus melakukan?)
# Asumsi sederhana: PIC adalah subjek sebelum kata indikator, biasanya diawali huruf kapital
words_before_task = sentence[:sentence.lower().find("harus") if "harus" in sentence.lower() else len(sentence)]
pic_match = re.findall(self.pic_pattern, words_before_task)
if pic_match:
pic = pic_match[-1] # Ambil entitas terakhir sebelum indikator tugas
# 3. Cari Deadline
for d_pattern in self.deadline_indicators:
d_match = re.search(d_pattern, sentence, re.IGNORECASE)
if d_match:
deadline = d_match.group(1).strip().split('.')[0].split(',')[0]
break
# Format output
action_items.append(f"{pic} -> {task} -> {deadline}")
return action_items
# Example usage:
# extractor = ActionItemExtractor()
# items = extractor.extract_action_items("Budi harus menyusun laporan keuangan paling lambat Jumat depan.")
# print(items) # Budi -> menyusun laporan keuangan -> Jumat depan