Skip to content

Commit 42cbea4

Browse files
add extract entitas
1 parent ccec25f commit 42cbea4

File tree

8 files changed

+89
-21
lines changed

8 files changed

+89
-21
lines changed

_includes/chat-launcher.html

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
<div id="suggestions" class="relative z-[9999] flex flex-wrap gap-2 px-3 py-2 text-sm text-gray-300 border-b border-gray-800 bg-gray-900 z-80">
2-
<button class="cursor-pointer bg-gray-700 px-3 py-1 rounded-full hover:bg-gray-600" data-suggest="Cari repo animasi tailwind">Cari repo animasi tailwind</button>
32
<button class="cursor-pointer bg-gray-700 px-3 py-1 rounded-full hover:bg-gray-600" data-suggest="ada repo AI chatbot?">ada repo AI chatbot?</button>
43
<button class="cursor-pointer bg-gray-700 px-3 py-1 rounded-full hover:bg-gray-600" data-suggest="repo yang trending?">repo yang trending?</button>
54
<div id="ai-notice" class="text-gray-400 text-sm hidden md:block px-3 py-1 italic"></div>

assets/js/core/core-ai.js

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import {
55
resetVoiceFlag,
66
setVoiceFlag
77
} from '../voice-engine.js';
8-
import { detectIntent } from '../intents-github.js';
8+
import { detectIntent, extractEntity } from '../intents-github.js';
99
import { detectIntentVn } from '../detectIntentVn.js';
1010
import { renderMarkdown, renderCardsFromAI } from '../render.js';
1111
import { buildPrompt } from '../promptBuilder-github.js';
@@ -34,17 +34,18 @@ setupVoiceRecognition(micBtn, async (transcript) => {
3434
setVoiceFlag();
3535
renderVoiceMessage("user", null, "voice note dikirim");
3636

37+
const entities = detectIntent(transcript);
3738
const intent = detectIntent(transcript); // ✅ intent berdasarkan VN
3839
const intentVn = detectIntentVn(transcript);
3940
const card = renderGithubCard(repo); // repo: object satuan dari GitHub
4041
messages.innerHTML += card;
4142

42-
if (intent === "github_search") {
43+
if (entities === "github_search") {
4344
await handleGithubSearchIntent(userMessage, messages);
4445
setTimeout(() => scrollToBottom(), 0);
4546
return;
4647
}
47-
const prompt = buildPrompt(transcript, intent, intentVn); // ✅ arahkan ke prompt AI
48+
const prompt = buildPrompt(transcript, intent, entities, intentVn); // ✅ arahkan ke prompt AI
4849

4950
addTyping();
5051
try {
@@ -113,7 +114,7 @@ launcherInput.addEventListener("blur", () => {
113114
if (!allowed.includes(isActive?.id)) {
114115
resetLauncher();
115116
}
116-
}, 100);
117+
}, 200);
117118
});
118119

119120
if (messages) {
@@ -147,14 +148,14 @@ if (chatWrapper) {
147148
launcherInput.focus();
148149
hideWelcomeMessage();
149150

150-
const intent = detectIntent(message);
151+
const entities = detectIntent(message);
151152

152-
if (intent === "github_search") {
153+
if (entities === "github_search") {
153154
await handleGithubSearchIntent(message, messages);
154155
return;
155156
}
156157

157-
const prompt = buildPrompt(message, intent);
158+
const prompt = buildPrompt(message, entities);
158159
addTyping();
159160

160161
try {

assets/js/githubSearchHandler.js

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,8 @@ export async function handleGithubSearchIntent(userMessage, chatBox) {
2828
// Prioritas 3 (Fallback): Anggap seluruh pesan sebagai kata kunci
2929
// Ini akan digunakan jika tidak ada pola di atas yang cocok
3030
// Hati-hati dengan fallback ini, pastikan tidak menangkap input yang terlalu ambigu
31-
if (!['repo', 'repositori', 'cari'].includes(normalizedMessage) &&
31+
if (!['repo', 'repositori', 'cari', 'ada'].includes(normalizedMessage) &&
32+
!normalizedMessage.startsWith('ada ') &&
3233
!normalizedMessage.startsWith('repo ') &&
3334
!normalizedMessage.startsWith('repositori ') &&
3435
!normalizedMessage.startsWith('cari ')) {
@@ -50,6 +51,7 @@ export async function handleGithubSearchIntent(userMessage, chatBox) {
5051
const repos = await searchGithubRepos(keyword);
5152
if (repos.length === 0) {
5253
chatBox.innerHTML += `<p class='text-gray-400'>Tidak ada repositori ditemukan untuk <strong>${keyword}</strong></p>`;
54+
document.getElementById('loadingMessage')?.remove();
5355
return;
5456
}
5557

assets/js/intents-github.js

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,5 +16,43 @@ export const detectIntent = (message) => {
1616
if (msg.match(/bantuan|help|fitur|apa bisa|ngapain aja/)) return "help";
1717
if (msg.match(/siapa kamu|kamu siapa|tentangmu|profil|creator|pembuat|yang buat kamu/)) return "about_ai";
1818

19+
20+
// Mencari Pengguna (User)
21+
if (msg.match(/cari user|user github|profil github|akun github|pengguna github|cari pengguna|siapa user/)) {
22+
return "github_search_user";
23+
}
24+
// Mencari Organisasi (Organization)
25+
if (msg.match(/cari organisasi|organisasi github|org github|organisasi apa/)) {
26+
return "github_search_organization";
27+
}
28+
// Mencari Kode (Code)
29+
if (msg.match(/cari kode|lihat kode|potongan kode|fungsi apa|contoh kode|implementasi kode/)) {
30+
return "github_search_code";
31+
}
32+
// Mencari Isu/Pull Request (Issues/PRs)
33+
if (msg.match(/cari isu|lihat isu|open issue|bug di|error di|problem di|pull request|pr di|masalah di/)) {
34+
return "github_search_issue";
35+
}
36+
// Mencari Topik (Topic)
37+
if (msg.match(/cari topik|topik github|tentang topik|ada topik/)) {
38+
return "github_search_topic";
39+
}
40+
// Mencari Repositori (Repo) - ini akan menjadi fallback untuk pencarian GitHub umum
41+
if (msg.match(/cari repo|repositori|proyek github|project di github|repo github|lihat repo|kode di github/)) {
42+
return "github_search_repository";
43+
}
44+
1945
return "fallback";
2046
};
47+
48+
export const extractEntity = (message, intent) => {
49+
const msg = message.toLowerCase();
50+
if (intent === "github_search_user") {
51+
const match = msg.match(/(?:user|pengguna)\s+([\w.-]+)/); // Mencari kata setelah 'user' atau 'pengguna'
52+
if (match && match[1]) {
53+
return { username: match[1] };
54+
}
55+
}
56+
// Tambahkan logika untuk intent lain (misalnya, nama repo, kata kunci kode, dll.)
57+
return null;
58+
};

assets/js/intents.js

Lines changed: 33 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,48 @@
11
// intents.js
22

33
/**
4-
* Mendeteksi intent user berdasarkan kata kunci dari pesan teks.
5-
* Digunakan oleh AI chatbot untuk merespons lebih tepat.
4+
* Mendeteksi intent pengguna berdasarkan kata kunci dari pesan teks.
5+
* Lebih fokus dan spesifik untuk berbagai jenis pencarian GitHub.
66
*/
77
export const detectIntent = (message) => {
88
const msg = message.toLowerCase();
99

10+
// Umum
1011
if (msg.match(/halo|hai|hi|assalam|pagi|siang|sore/)) return "greeting";
11-
if (msg.match(/repo|repositori|github|cari repo|cari proyek|lihat kode/)) return "github_search";
1212
if (msg.match(/cerita|kisah|buatkan cerita|dongeng|kisahkan|story/)) return "make_story";
1313
if (msg.match(/lanjut cerita|teruskan cerita|next chapter|continue/)) return "continue_story";
1414
if (msg.match(/hapus|reset|mulai ulang|clear/)) return "reset_conversation";
1515
if (msg.match(/daftar|subscribe|langganan|premium/)) return "subscribe_prompt";
1616
if (msg.match(/bantuan|help|fitur|apa bisa|ngapain aja/)) return "help";
17-
if (msg.match(/siapa kamu|kamu siapa|tentangmu|profil|creator|pembuat|yang buat kamu/)) return "about_ai";
17+
if (msg.match(/siapa kamu|kamu siapa|tentangmu|profil|creator|pembuat|pencipta|yang buat kamu|yng bikin kamu/)) return "about_ai";
18+
19+
// Intent Spesifik GitHub
20+
// Prioritaskan intent yang lebih spesifik terlebih dahulu
21+
22+
// Mencari Pengguna (User)
23+
if (msg.match(/cari user|user github|profil github|akun github|pengguna github|cari pengguna|siapa user/)) {
24+
return "github_search_user";
25+
}
26+
// Mencari Organisasi (Organization)
27+
if (msg.match(/cari organisasi|organisasi github|org github|organisasi apa/)) {
28+
return "github_search_organization";
29+
}
30+
// Mencari Kode (Code)
31+
if (msg.match(/cari kode|lihat kode|potongan kode|fungsi apa|contoh kode|implementasi kode/)) {
32+
return "github_search_code";
33+
}
34+
// Mencari Isu/Pull Request (Issues/PRs)
35+
if (msg.match(/cari isu|lihat isu|open issue|bug di|error di|problem di|pull request|pr di|masalah di/)) {
36+
return "github_search_issue";
37+
}
38+
// Mencari Topik (Topic)
39+
if (msg.match(/cari topik|topik github|tentang topik|ada topik/)) {
40+
return "github_search_topic";
41+
}
42+
// Mencari Repositori (Repo) - ini akan menjadi fallback untuk pencarian GitHub umum
43+
if (msg.match(/cari repo|repositori|proyek github|project di github|repo github|lihat repo|kode di github/)) {
44+
return "github_search_repository";
45+
}
1846

1947
return "fallback";
20-
};
48+
};

assets/js/render.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ export function renderCardsFromAI(replyText) {
2525
if (!cards.length) return "";
2626

2727
const html = cards.map(c => `
28-
<div class="border overflow-hidden border-gray-700 rounded-lg mb-4 overflow-hidden bg-gray-800 shadow">
28+
<div id="grid" class="border overflow-hidden border-gray-700 rounded-lg mb-4 overflow-hidden bg-gray-800 shadow">
2929
${c.img ? `<img src="${c.img}" alt="${c.title}" class="w-full h-40 object-cover" />` : ''}
3030
<div class="p-3">
3131
<h3 class="text-white font-semibold">${c.title}</h3>
@@ -44,7 +44,7 @@ export function renderCardsFromAI(replyText) {
4444
*/
4545
export function renderRepoCards(repoArray) {
4646
return repoArray.map(p => `
47-
<div class="border overflow-hidden border-gray-700 rounded-lg mb-4 overflow-hidden bg-gray-800 shadow">
47+
<div id="grid" class="border overflow-hidden border-gray-700 rounded-lg mb-4 overflow-hidden bg-gray-800 shadow">
4848
<img src="${p.img}" alt="${p.title}" class="w-full h-40 object-cover" />
4949
<div class="p-3">
5050
<h3 class="text-white font-semibold">${p.title}</h3>

assets/js/renderGithubCards.js

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -26,16 +26,16 @@ export function renderGithubCard(repo) {
2626
if (!repo || typeof repo !== "object") return "";
2727

2828
return `
29-
<div id="grid" class="border w-fit cursor-pointer overflow-hidden border-gray-700 bg-gray-800 rounded-md p-4 shadow-md flex gap-4 items-start my-4 transition-transform hover:scale-[1.02]" data-repo-owner="${repo?.owner?.login}" data-repo-fullname="${repo?.full_name}">
29+
<div id="grid" class="border w-fit cursor-pointer overflow-hidden border-gray-700 bg-gray-800 rounded-md p-4 shadow-md flex gap-4 items-start my-4 transition-transform hover:scale-[1.02]" data-repo-owner="${repo?.owner?.login || ""}" data-repo-fullname="${repo?.full_name || ""}">
3030
<img src="${repo.owner?.avatar_url || "./assets/images/logo.png"}" alt="Avatar" class="w-14 h-14 rounded-full object-cover" />
3131
<div>
3232
<div>
33-
<a href="${repo.html_url}" target="_blank" class="text-blue-400 font-bold text-base hover:underline">
33+
<a href="${repo.html_url || "https://github.com/daffadevhosting/daffadevhosting.github.io"}" target="_blank" class="text-blue-400 font-bold text-base hover:underline">
3434
${repo.full_name ? repo.full_name.slice(0, 25) + (repo.full_name.length > 15 ? '...' : '') : "L Y Я A"}
3535
</a>
3636
<p class="text-gray-300 text-sm mt-1">${repo.description ? repo.description.slice(0, 150) + (repo.description.length > 180 ? '...' : '') : "AI Custom User-Agent "}</p>
3737
<div class="flex gap-2 justify-between items-center">
38-
<p class="text-yellow-400 text-xs mt-2">⭐ ${repo.stargazers_count?.toLocaleString() ?? '500'} stars</p>
38+
<p class="text-yellow-400 text-xs mt-2">⭐ ${repo.stargazers_count?.toLocaleString() ?? '0'} stars</p>
3939
<p class="text-green-400 text-xs mt-2">${repo.language || 'Jekyll, Javascript'}</p>
4040
</div>
4141
</div>

assets/js/voiceFlow.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { renderVoiceMessage } from './voice.js';
2-
import { speakWithTTS } from './tts-clean.js';
2+
import { speakWithTTS } from './tts.js';
33

44
let isVoiceMode = false;
55
let lastReply = "";
@@ -55,7 +55,7 @@ function addBotMessage(text) {
5555
const box = document.getElementById("chat-messages");
5656
const bubble = document.createElement("div");
5757
bubble.className = "text-left text-gray-300 my-2 text-sm";
58-
bubble.innerHTML = text; // bisa diparse dengan marked
58+
bubble.innerHTML = `<strong>LYRA:</strong><br>${text}`; // bisa diparse dengan marked
5959
box.appendChild(bubble);
6060
box.scrollTop = box.scrollHeight;
6161
}

0 commit comments

Comments
 (0)