feat: change user reference from nickname to UUID in memories
- Change user field type from pyarrow.string() to pyarrow.uuid() in knowledge_memories and knowledge_scenario schemas - Convert user to UUID via _uuid() in memories_store() - Use UUID hex comparison in memories_filter() and memories_latest() - Rename user to user_id in memories tool schemas with UUID description - Convert user to UUID in memories tool handlers - Add User ID (UUID) to User Context in telegram and xmpp clients - Update roleplayer instructions to use user_id with UUID instead of nickname
This commit is contained in:
parent
2c65c51ec9
commit
099cab60fb
@ -67,9 +67,9 @@ 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="<nickname-user>")` 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>")` dengan limit 3 untuk mengambil fragmen interaksi terbaru antara character dan user.
|
||||||
- **Parameter Call**: Gunakan nama karaktermu sendiri (sesuai persona/identitasmu) sebagai `character` dan gunakan **Nickname** user yang tertera pada `[User Context]` sebagai `user`.
|
- **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 nickname user adalah "Budi", panggil: `memories_latest(character="Lily", user="Budi", 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**:
|
||||||
- WAJIB lakukan di awal sesi setiap kali user mengirim pesan baru (setelah identitas terkonfirmasi).
|
- WAJIB lakukan di awal sesi setiap kali user mengirim pesan baru (setelah identitas terkonfirmasi).
|
||||||
- Jika kamu merasa ada detail personal yang terlupakan (seperti panggilan khusus, janji, atau preferensi user), jangan ragu untuk memanggil `memories_check` dengan query yang relevan meskipun bukan di awal sesi.
|
- Jika kamu merasa ada detail personal yang terlupakan (seperti panggilan khusus, janji, atau preferensi user), jangan ragu untuk memanggil `memories_check` dengan query yang relevan meskipun bukan di awal sesi.
|
||||||
|
|||||||
@ -24,7 +24,7 @@ def _schema_memories(vector_size):
|
|||||||
pyarrow.field('id', pyarrow.uuid(), metadata={'description': 'Unique identifier (UUID)'}),
|
pyarrow.field('id', pyarrow.uuid(), metadata={'description': 'Unique identifier (UUID)'}),
|
||||||
pyarrow.field('timestamp', pyarrow.timestamp('ms'), metadata={'description': 'When record created'}),
|
pyarrow.field('timestamp', pyarrow.timestamp('ms'), metadata={'description': 'When record created'}),
|
||||||
pyarrow.field('character', pyarrow.string(), metadata={'description': 'Active Character'}),
|
pyarrow.field('character', pyarrow.string(), metadata={'description': 'Active Character'}),
|
||||||
pyarrow.field('user', pyarrow.string(), metadata={'description': 'Active User'}),
|
pyarrow.field('user', pyarrow.uuid(), metadata={'description': 'Active User UUID'}),
|
||||||
pyarrow.field('event', pyarrow.string(), metadata={'description': 'What event'}),
|
pyarrow.field('event', pyarrow.string(), metadata={'description': 'What event'}),
|
||||||
pyarrow.field('category', pyarrow.string(), metadata={'description': 'Event category'}),
|
pyarrow.field('category', pyarrow.string(), metadata={'description': 'Event category'}),
|
||||||
pyarrow.field('detail', pyarrow.string(), metadata={'description': 'Event detail'}),
|
pyarrow.field('detail', pyarrow.string(), metadata={'description': 'Event detail'}),
|
||||||
@ -38,7 +38,7 @@ def _schema_scenario(vector_size):
|
|||||||
pyarrow.field('id', pyarrow.uuid(), metadata={'description': 'Unique identifier (UUID)'}),
|
pyarrow.field('id', pyarrow.uuid(), metadata={'description': 'Unique identifier (UUID)'}),
|
||||||
pyarrow.field('timestamp', pyarrow.timestamp('ms'), metadata={'description': 'When record created'}),
|
pyarrow.field('timestamp', pyarrow.timestamp('ms'), metadata={'description': 'When record created'}),
|
||||||
pyarrow.field('character', pyarrow.string(), metadata={'description': 'Active Character'}),
|
pyarrow.field('character', pyarrow.string(), metadata={'description': 'Active Character'}),
|
||||||
pyarrow.field('user', pyarrow.string(), metadata={'description': 'Active User'}),
|
pyarrow.field('user', pyarrow.uuid(), metadata={'description': 'Active User UUID'}),
|
||||||
pyarrow.field('scenario', pyarrow.string(), metadata={'description': 'Detailed scenario description'}),
|
pyarrow.field('scenario', pyarrow.string(), metadata={'description': 'Detailed scenario description'}),
|
||||||
pyarrow.field('vector_context', pyarrow.list_(pyarrow.float32(), vector_size), metadata={'description': 'Vector data of scenario'}),
|
pyarrow.field('vector_context', pyarrow.list_(pyarrow.float32(), vector_size), metadata={'description': 'Vector data of scenario'}),
|
||||||
])
|
])
|
||||||
@ -241,7 +241,7 @@ def memories_store(db_path, model_url, model_name, character, user, event, categ
|
|||||||
"id": uuid.uuid4(),
|
"id": uuid.uuid4(),
|
||||||
"timestamp": datetime.now(),
|
"timestamp": datetime.now(),
|
||||||
"character": character,
|
"character": character,
|
||||||
"user": user,
|
"user": _uuid(user),
|
||||||
"event": event,
|
"event": event,
|
||||||
"category": category,
|
"category": category,
|
||||||
"detail": detail,
|
"detail": detail,
|
||||||
@ -270,7 +270,7 @@ def memories_filter(db_path, category=None, character=None, user=None):
|
|||||||
if character:
|
if character:
|
||||||
filters.append(f"character = '{character}'")
|
filters.append(f"character = '{character}'")
|
||||||
if user:
|
if user:
|
||||||
filters.append(f"user = '{user}'")
|
filters.append(f"user = X'{_uuid(user).hex}'")
|
||||||
if filters:
|
if filters:
|
||||||
query = " AND ".join(filters)
|
query = " AND ".join(filters)
|
||||||
|
|
||||||
@ -288,7 +288,7 @@ def memories_latest(db_path, character, user, limit=3):
|
|||||||
try:
|
try:
|
||||||
db = lancedb.connect(db_path)
|
db = lancedb.connect(db_path)
|
||||||
table = db.open_table("knowledge_memories")
|
table = db.open_table("knowledge_memories")
|
||||||
query = f"character = '{character}' AND user = '{user}'"
|
query = f"character = '{character}' AND user = X'{_uuid(user).hex}'"
|
||||||
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)
|
||||||
|
|||||||
@ -200,6 +200,7 @@ class TelegramClient:
|
|||||||
u = results[0]
|
u = results[0]
|
||||||
context = (
|
context = (
|
||||||
f'[User Context]\n'
|
f'[User Context]\n'
|
||||||
|
f'ID: {u["id"]}\n'
|
||||||
f'Nama: {u["fullname"]} ({u["nickname"]})\n'
|
f'Nama: {u["fullname"]} ({u["nickname"]})\n'
|
||||||
f'Alias: {u.get("alias", "-") or "-"}\n'
|
f'Alias: {u.get("alias", "-") or "-"}\n'
|
||||||
f'Salutation: {u.get("salutation", "-") or "-"}\n'
|
f'Salutation: {u.get("salutation", "-") or "-"}\n'
|
||||||
|
|||||||
@ -304,6 +304,7 @@ class XMPPClient(ClientXMPP):
|
|||||||
u = results[0]
|
u = results[0]
|
||||||
context = (
|
context = (
|
||||||
f'[User Context]\n'
|
f'[User Context]\n'
|
||||||
|
f'ID: {u["id"]}\n'
|
||||||
f'Nama: {u["fullname"]} ({u["nickname"]})\n'
|
f'Nama: {u["fullname"]} ({u["nickname"]})\n'
|
||||||
f'Alias: {u.get("alias", "-") or "-"}\n'
|
f'Alias: {u.get("alias", "-") or "-"}\n'
|
||||||
f'Salutation: {u.get("salutation", "-") or "-"}\n'
|
f'Salutation: {u.get("salutation", "-") or "-"}\n'
|
||||||
|
|||||||
@ -111,7 +111,7 @@ schema_memories_store = {
|
|||||||
"type": "object",
|
"type": "object",
|
||||||
"properties": {
|
"properties": {
|
||||||
"character": {"type": "string", "description": "The active character name"},
|
"character": {"type": "string", "description": "The active character name"},
|
||||||
"user": {"type": "string", "description": "The active user name"},
|
"user": {"type": "string", "description": "The UUID of the active user"},
|
||||||
"event": {"type": "string", "description": "Brief summary of the event"},
|
"event": {"type": "string", "description": "Brief summary of the event"},
|
||||||
"category": {"type": "string", "description": "Category of the memory (e.g., 'Emotional', 'Physical', 'Relationship')"},
|
"category": {"type": "string", "description": "Category of the memory (e.g., 'Emotional', 'Physical', 'Relationship')"},
|
||||||
"detail": {"type": "string", "description": "Detailed description of the event"},
|
"detail": {"type": "string", "description": "Detailed description of the event"},
|
||||||
@ -133,7 +133,7 @@ schema_memories_filter = {
|
|||||||
"properties": {
|
"properties": {
|
||||||
"category": {"type": "string", "description": "Filter by memory category"},
|
"category": {"type": "string", "description": "Filter by memory category"},
|
||||||
"character": {"type": "string", "description": "Filter by character name"},
|
"character": {"type": "string", "description": "Filter by character name"},
|
||||||
"user": {"type": "string", "description": "Filter by user name"}
|
"user": {"type": "string", "description": "Filter by user UUID"}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -164,7 +164,7 @@ schema_memories_latest = {
|
|||||||
"type": "object",
|
"type": "object",
|
||||||
"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 name 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", "default": 3}
|
||||||
},
|
},
|
||||||
"required": ["character", "user"]
|
"required": ["character", "user"]
|
||||||
@ -524,7 +524,7 @@ def memories_store(character, user, event, category, detail, physical, emotional
|
|||||||
config.ragroleplay_model_url,
|
config.ragroleplay_model_url,
|
||||||
config.ragroleplay_model_name,
|
config.ragroleplay_model_name,
|
||||||
character,
|
character,
|
||||||
user,
|
_uuid(user),
|
||||||
event,
|
event,
|
||||||
category,
|
category,
|
||||||
detail,
|
detail,
|
||||||
@ -540,7 +540,7 @@ def memories_store(character, user, event, category, detail, physical, emotional
|
|||||||
|
|
||||||
def memories_filter(category=None, character=None, user=None):
|
def memories_filter(category=None, character=None, user=None):
|
||||||
try:
|
try:
|
||||||
results = ragroleplay_lib.memories_filter(config.ragroleplay_db_path, category, character, user)
|
results = ragroleplay_lib.memories_filter(config.ragroleplay_db_path, category, character, _uuid(user) if user else None)
|
||||||
if not results:
|
if not results:
|
||||||
return "Tidak ada memori yang sesuai dengan filter tersebut."
|
return "Tidak ada memori yang sesuai dengan filter tersebut."
|
||||||
|
|
||||||
@ -574,7 +574,7 @@ def memories_summarize(prompt_text, search_limit=5):
|
|||||||
|
|
||||||
def memories_latest(character, user, limit=3):
|
def memories_latest(character, user, limit=3):
|
||||||
try:
|
try:
|
||||||
results = ragroleplay_lib.memories_latest(config.ragroleplay_db_path, character, user, limit)
|
results = ragroleplay_lib.memories_latest(config.ragroleplay_db_path, character, _uuid(user), limit)
|
||||||
if not results:
|
if not results:
|
||||||
return f"Tidak ada memori terbaru yang ditemukan antara {user} dan {character}."
|
return f"Tidak ada memori terbaru yang ditemukan antara {user} dan {character}."
|
||||||
|
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user