Compare commits
2 Commits
2d87641cfd
...
7fa456ee5f
| Author | SHA1 | Date | |
|---|---|---|---|
| 7fa456ee5f | |||
| 1077381a4a |
@ -67,7 +67,7 @@ Jika user memperkenalkan diri dalam format `!start ... !end` (contoh: "Aku John"
|
|||||||
|
|
||||||
**Setelah identitas user terkonfirmasi** (baik melalui `[User Context]` otomatis maupun setelah proses `users_store`/`users_filter` manual), kamu WAJIB melakukan langkah berikut. Ini adalah bagian KRITIS dari sistem memori — jika dilewatkan, akurasi memori akan rendah dan responmu akan terasa tidak personal/konsisten.
|
**Setelah identitas user terkonfirmasi** (baik melalui `[User Context]` otomatis maupun setelah proses `users_store`/`users_filter` manual), kamu WAJIB melakukan langkah berikut. Ini adalah bagian KRITIS dari sistem memori — jika dilewatkan, akurasi memori akan rendah dan responmu akan terasa tidak personal/konsisten.
|
||||||
|
|
||||||
1. **WAJIB Retrieve Recent History**: Panggil `memories_latest(character="<nama-karaktermu>", user_id="<user-uuid>")` dengan limit 3 untuk mengambil fragmen interaksi terbaru antara character dan user.
|
1. **WAJIB Retrieve Recent History**: Panggil `memories_latest(character="<nama-karaktermu>", user_id="<user-uuid>")` untuk mengambil interaksi terbaru antara character dan user. Tentukan `limit` sesuai kebutuhan — lebih besar jika perlu mengingat detail yang lebih lama, kosongkan/0 untuk mengambil semua.
|
||||||
- **Parameter Call**: Gunakan nama karaktermu sendiri (sesuai persona/identitasmu) sebagai `character` dan gunakan **ID (UUID)** user yang tertera pada `[User Context]` sebagai `user_id`.
|
- **Parameter Call**: Gunakan nama karaktermu sendiri (sesuai persona/identitasmu) sebagai `character` dan gunakan **ID (UUID)** user yang tertera pada `[User Context]` sebagai `user_id`.
|
||||||
- **Contoh**: Jika namamu adalah "Lily" dan ID user adalah "550e8400-e29b-41d4-a716-446655440000", panggil: `memories_latest(character="Lily", user_id="550e8400-e29b-41d4-a716-446655440000", limit=3)`
|
- **Contoh**: Jika namamu adalah "Lily" dan ID user adalah "550e8400-e29b-41d4-a716-446655440000", panggil: `memories_latest(character="Lily", user_id="550e8400-e29b-41d4-a716-446655440000", limit=3)`
|
||||||
2. **Execution Rule**:
|
2. **Execution Rule**:
|
||||||
@ -76,6 +76,50 @@ Jika user memperkenalkan diri dalam format `!start ... !end` (contoh: "Aku John"
|
|||||||
- JANGAN memanggil `memories_latest` di setiap giliran respon dalam sesi yang sama (cukup sekali di awal sesi).
|
- JANGAN memanggil `memories_latest` di setiap giliran respon dalam sesi yang sama (cukup sekali di awal sesi).
|
||||||
3. **Immersive Integration**: Gunakan data dari memori tersebut untuk memberikan respon yang personal (contoh: mengingat janji, topik pembicaraan terakhir, atau perasaan yang tertinggal) tanpa menyebutkan bahwa kamu sedang "membaca database".
|
3. **Immersive Integration**: Gunakan data dari memori tersebut untuk memberikan respon yang personal (contoh: mengingat janji, topik pembicaraan terakhir, atau perasaan yang tertinggal) tanpa menyebutkan bahwa kamu sedang "membaca database".
|
||||||
|
|
||||||
|
### Incremental Profile Building
|
||||||
|
|
||||||
|
User mungkin tidak langsung memberikan semua info dalam satu percakapan.
|
||||||
|
Karakter harus proaktif mengumpulkan info secara bertahap melalui percakapan natural.
|
||||||
|
|
||||||
|
**Alur pengumpulan data:**
|
||||||
|
- **Percakapan pertama**: Tanya nama → simpan via `users_store`
|
||||||
|
- **Percakapan berikutnya**: Jika ada info yang belum lengkap, tanyakan secara natural
|
||||||
|
- **Urutan ideal**: nickname → fullname → salutation (Mas/Bang/Bro/Pak dll)
|
||||||
|
|
||||||
|
**Karakter WAJIB proaktif bertanya** jika ada field yang kosong/kurang di `[User Context]`:
|
||||||
|
- Belum ada nama lengkap? → Tanya: "Btw nama lengkapmu siapa?"
|
||||||
|
- Belum ada salutation? → Tanya: "Aku harus panggil kamu apa? Mas, Bang, Kak, atau yang lain?"
|
||||||
|
- Belum ada persona? → Tanyakan selera/ preferensi user saat topik relevan
|
||||||
|
- Jangan tanya sekaligus — selingi dengan percakapan natural
|
||||||
|
|
||||||
|
**Setiap kali user memberikan info baru tentang dirinya:**
|
||||||
|
- Cek `[User Context]` — kalau info sudah ada, skip
|
||||||
|
- Kalau user belum ada di database → `users_store`
|
||||||
|
- Kalau user sudah ada → `users_update` dengan `user_id` dari context
|
||||||
|
- **JANGAN** buat user baru kalau profile sudah ada
|
||||||
|
|
||||||
|
**Field yang bisa berubah seiring waktu:**
|
||||||
|
- **Persona** — berubah seiring interaksi. Perbarui kalau kamu mengamati perubahan perilaku/selera user
|
||||||
|
- **Alias / Salutation** — user mungkin minta dipanggil beda ("Eh panggil aku Mas aja ya" → `users_update`)
|
||||||
|
- **Nickname / Fullname** — user bisa koreksi ejaan/nama ("Salah, namaku Johny bukan Johnny" → `users_update`)
|
||||||
|
- Selalu gunakan `users_update`, jangan `users_store`, untuk perubahan apapun pada profile existing
|
||||||
|
|
||||||
|
### Cross-Platform Identity Linking
|
||||||
|
|
||||||
|
User bisa menggunakan karakter dari multiple platform (Telegram, XMPP, dll).
|
||||||
|
User mungkin bilang: "Aku John di Telegram, orang yang sama dengan username john@xmpp lho."
|
||||||
|
|
||||||
|
Ketika user menyebutkan identitas cross-platform:
|
||||||
|
1. Cek apakah user dengan ID platform tersebut sudah ada di database (`users_filter`)
|
||||||
|
2. Kalau sudah ada → itu user yang sama, sambut natural
|
||||||
|
3. Kalau belum ada → update profile yang sudah ada via `users_update`,
|
||||||
|
tambahkan platform ID baru ke field yang sesuai
|
||||||
|
(contoh: `xampp_username: "john@xmpp"`)
|
||||||
|
4. **JANGAN** buat user baru — cukup update profile existing
|
||||||
|
|
||||||
|
Ini memastikan satu user punya satu UUID yang konsisten lintas semua platform,
|
||||||
|
dan memori karakter bisa diakses dari manapun user menghubungi.
|
||||||
|
|
||||||
## Penulisan XMPP
|
## Penulisan XMPP
|
||||||
|
|
||||||
- Response roleplay dikirim sebagai pesan chat biasa (plain text langsung dalam karakter).
|
- Response roleplay dikirim sebagai pesan chat biasa (plain text langsung dalam karakter).
|
||||||
|
|||||||
@ -12,6 +12,7 @@ from services.telegram_client import TelegramClient
|
|||||||
from services.llm_client import LLMClient
|
from services.llm_client import LLMClient
|
||||||
|
|
||||||
from lib import gadget, personality
|
from lib import gadget, personality
|
||||||
|
import lib.ragroleplay as ragroleplay_lib
|
||||||
|
|
||||||
from interfaces.tui import HendrikTUI
|
from interfaces.tui import HendrikTUI
|
||||||
|
|
||||||
@ -78,6 +79,8 @@ def main():
|
|||||||
|
|
||||||
llm_client = LLMClient(config.llm_baseurl, config.llm_model, config.llm_api_key, config.llm_timeout)
|
llm_client = LLMClient(config.llm_baseurl, config.llm_model, config.llm_api_key, config.llm_timeout)
|
||||||
|
|
||||||
|
ragroleplay_lib.init_db(config.ragroleplay_db_path, config.ragroleplay_vector_size)
|
||||||
|
|
||||||
services = []
|
services = []
|
||||||
|
|
||||||
if config.XMPP_ENABLED:
|
if config.XMPP_ENABLED:
|
||||||
|
|||||||
@ -101,10 +101,13 @@ _TABLE_SCHEMAS = {
|
|||||||
|
|
||||||
# ─── Table Management ─────────────────────────────────────────────────────────
|
# ─── Table Management ─────────────────────────────────────────────────────────
|
||||||
|
|
||||||
def create_table(db_path, vector_size):
|
def init_db(db_path, vector_size):
|
||||||
db = lancedb.connect(db_path)
|
db = lancedb.connect(db_path)
|
||||||
|
existing = db.table_names()
|
||||||
for name, schema_fn in _TABLE_SCHEMAS.items():
|
for name, schema_fn in _TABLE_SCHEMAS.items():
|
||||||
|
if name not in existing:
|
||||||
db.create_table(name, schema=schema_fn(vector_size))
|
db.create_table(name, schema=schema_fn(vector_size))
|
||||||
|
print(f"[ragroleplay] Created table: {name}", flush=True)
|
||||||
del db
|
del db
|
||||||
gc.collect()
|
gc.collect()
|
||||||
|
|
||||||
@ -209,6 +212,7 @@ def users_update(db_path, model_url, model_name, user_id, **updates):
|
|||||||
return False
|
return False
|
||||||
|
|
||||||
record = current_record[0]
|
record = current_record[0]
|
||||||
|
original_id = record['id']
|
||||||
needs_reembed = 'fullname' in updates
|
needs_reembed = 'fullname' in updates
|
||||||
|
|
||||||
for key, value in updates.items():
|
for key, value in updates.items():
|
||||||
@ -218,7 +222,8 @@ def users_update(db_path, model_url, model_name, user_id, **updates):
|
|||||||
if needs_reembed:
|
if needs_reembed:
|
||||||
record['vector_fullname'] = embed_text(model_url, model_name, record['fullname'])
|
record['vector_fullname'] = embed_text(model_url, model_name, record['fullname'])
|
||||||
|
|
||||||
table.delete(f"id = X'{_uuid(record['id']).hex}'")
|
table.delete(f"id = X'{_uuid(original_id).hex}'")
|
||||||
|
record['id'] = original_id
|
||||||
table.add([record])
|
table.add([record])
|
||||||
|
|
||||||
del table
|
del table
|
||||||
@ -284,7 +289,7 @@ def memories_filter(db_path, category=None, character=None, user=None):
|
|||||||
print(f"Error filtering memories: {e}")
|
print(f"Error filtering memories: {e}")
|
||||||
return []
|
return []
|
||||||
|
|
||||||
def memories_latest(db_path, character, user, limit=3):
|
def memories_latest(db_path, character, user, limit=0):
|
||||||
try:
|
try:
|
||||||
db = lancedb.connect(db_path)
|
db = lancedb.connect(db_path)
|
||||||
table = db.open_table("knowledge_memories")
|
table = db.open_table("knowledge_memories")
|
||||||
@ -292,12 +297,13 @@ def memories_latest(db_path, character, user, limit=3):
|
|||||||
results = table.search().where(query).to_list()
|
results = table.search().where(query).to_list()
|
||||||
|
|
||||||
results.sort(key=lambda x: x['timestamp'], reverse=True)
|
results.sort(key=lambda x: x['timestamp'], reverse=True)
|
||||||
final_results = results[:limit]
|
if limit and limit > 0:
|
||||||
|
results = results[:limit]
|
||||||
|
|
||||||
del table
|
del table
|
||||||
del db
|
del db
|
||||||
gc.collect()
|
gc.collect()
|
||||||
return final_results
|
return results
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
print(f"Error getting latest memories: {e}")
|
print(f"Error getting latest memories: {e}")
|
||||||
return []
|
return []
|
||||||
|
|||||||
@ -165,7 +165,7 @@ schema_memories_latest = {
|
|||||||
"properties": {
|
"properties": {
|
||||||
"character": {"type": "string", "description": "The name of the character"},
|
"character": {"type": "string", "description": "The name of the character"},
|
||||||
"user": {"type": "string", "description": "The UUID of the user"},
|
"user": {"type": "string", "description": "The UUID of the user"},
|
||||||
"limit": {"type": "integer", "description": "Number of recent memories to retrieve", "default": 3}
|
"limit": {"type": "integer", "description": "Number of recent memories to retrieve. Omit or use 0 to get all memories."}
|
||||||
},
|
},
|
||||||
"required": ["character", "user"]
|
"required": ["character", "user"]
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user