File size: 3,875 Bytes
2a16478
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
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