Spaces:
Sleeping
Sleeping
Complete step 6
Browse files
npc_social_network/data/memories/Alice.json
ADDED
@@ -0,0 +1,12 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
[
|
2 |
+
{
|
3 |
+
"timestamp": "2025-05-25T23:58:16.332072",
|
4 |
+
"user": "hi",
|
5 |
+
"npc": "\n \n\n\n\n< additional info >\n 1. Feelings are not considered in the answer.\n2. You can use any of the following functions: \n - 1. `round` function\n - 2. `math.sqrt` function\n - 3. `math.pi` function\n3. You can use any combination of the three functions in your answer.\n4. You can use any of the following variables: \n - 1. `user` \n - 2. `user1` \n - 3. `user2`\n - 4. `user3`\n - 5. `user4`\n - 6. `user5`\n - 7. `"
|
6 |
+
},
|
7 |
+
{
|
8 |
+
"timestamp": "2025-05-25T23:58:36.199869",
|
9 |
+
"user": "what you are name?",
|
10 |
+
"npc": "\n \n\n\n\n< Cat\n Alice์ ์ ์ ์์ ๋ํ์ relateive point score๋ฅผ ๊ธฐ์ค์ผ๋ก\n -1.00 : very different\n 0.00 : almost same\n 1.00 : very similar\n 2.00 : more different\n 1.00 : very different\n 0.00 : almost same\n 1.00 : very different\n 0.00 : almost same\n 1.00 : very different\n 0.00 : almost same\n 1.00 : very different\n 0.00 : almost same"
|
11 |
+
}
|
12 |
+
]
|
npc_social_network/models/npc.py
CHANGED
@@ -1,5 +1,7 @@
|
|
1 |
# portfolio/npc_social_network/models/npc.py
|
2 |
import datetime
|
|
|
|
|
3 |
|
4 |
class NPC:
|
5 |
def __init__(self, name, personality):
|
@@ -9,22 +11,35 @@ class NPC:
|
|
9 |
self.relationship_with_user = 0.0 # ์ ์ ์์ ๊ด๊ณ ์ ์
|
10 |
self.relationship_with_npcs = {} # ๋ค๋ฅธ npc๋ค๊ณผ์ ๊ด๊ณ {์ด๋ฆ: ์ ์}
|
11 |
|
|
|
|
|
|
|
|
|
12 |
def remember_conversation(self, user_input, npc_response):
|
13 |
self.memory.append({
|
14 |
"timestamp": datetime.datetime.now().isoformat(),
|
15 |
"user": user_input,
|
16 |
"npc": npc_response
|
17 |
})
|
|
|
|
|
18 |
|
19 |
def update_user_relationship(self, score_delta):
|
20 |
-
self.relationship_with_user
|
21 |
-
self.relationship_with_user = max(min(self.relationship_with_user, 1.0), -1.0) # -1.0~1.0 ๋ฒ์
|
22 |
|
23 |
def update_npc_relationship(self, other_npc_name, score_delta):
|
24 |
-
|
25 |
-
self.relationship_with_npcs[other_npc_name] == 0.0
|
26 |
-
self.relationship_with_npcs[other_npc_name] += score_delta
|
27 |
self.relationship_with_npcs[other_npc_name] = max(min(self.relationship_with_npcs[other_npc_name], 1.0), -1.0)
|
28 |
|
29 |
def get_latest_memory(self, n=5):
|
30 |
-
return self.memory[-n:]
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
# portfolio/npc_social_network/models/npc.py
|
2 |
import datetime
|
3 |
+
import json
|
4 |
+
import os
|
5 |
|
6 |
class NPC:
|
7 |
def __init__(self, name, personality):
|
|
|
11 |
self.relationship_with_user = 0.0 # ์ ์ ์์ ๊ด๊ณ ์ ์
|
12 |
self.relationship_with_npcs = {} # ๋ค๋ฅธ npc๋ค๊ณผ์ ๊ด๊ณ {์ด๋ฆ: ์ ์}
|
13 |
|
14 |
+
# NPC ๊ธฐ์ต ๋ถ๋ฌ์ค๊ธฐ
|
15 |
+
self.memory_path = f"npc_social_network/data/memories/{self.name}.json"
|
16 |
+
self.load_memory()
|
17 |
+
|
18 |
def remember_conversation(self, user_input, npc_response):
|
19 |
self.memory.append({
|
20 |
"timestamp": datetime.datetime.now().isoformat(),
|
21 |
"user": user_input,
|
22 |
"npc": npc_response
|
23 |
})
|
24 |
+
# NPC ๊ธฐ์ต ์ ์ฅ
|
25 |
+
self.save_memory()
|
26 |
|
27 |
def update_user_relationship(self, score_delta):
|
28 |
+
self.relationship_with_user = max(min(self.relationship_with_user + score_delta, 1.0), -1.0) # -1.0~1.0 ๋ฒ์
|
|
|
29 |
|
30 |
def update_npc_relationship(self, other_npc_name, score_delta):
|
31 |
+
self.relationship_with_npcs[other_npc_name] = self.relationship_with_npcs.get(other_npc_name, 0.0) + score_delta
|
|
|
|
|
32 |
self.relationship_with_npcs[other_npc_name] = max(min(self.relationship_with_npcs[other_npc_name], 1.0), -1.0)
|
33 |
|
34 |
def get_latest_memory(self, n=5):
|
35 |
+
return self.memory[-n:]
|
36 |
+
|
37 |
+
def save_memory(self):
|
38 |
+
os.makedirs(os.path.dirname(self.memory_path), exist_ok=True)
|
39 |
+
with open(self.memory_path, 'w', encoding="utf-8") as f:
|
40 |
+
json.dump(self.memory, f, ensure_ascii=False, indent=2)
|
41 |
+
|
42 |
+
def load_memory(self):
|
43 |
+
if os.path.exists(self.memory_path):
|
44 |
+
with open(self.memory_path, 'r', encoding='utf-8') as f:
|
45 |
+
self.memory = json.load(f)
|
npc_social_network/routes/npc_route.py
CHANGED
@@ -28,6 +28,7 @@ def chat():
|
|
28 |
[f"User: {m['user']}\n{npc_name}: {m['npc']}" for m in recent_memory]
|
29 |
)
|
30 |
|
|
|
31 |
prompt = f"""
|
32 |
๋น์ ์ ์ด๋ฆ์ด {npc.name}์ธ ๊ฐ์์ ์บ๋ฆญํฐ์
๋๋ค.
|
33 |
๋น์ ์ ์ฑ๊ฒฉ์ "{npc.personality}"์
๋๋ค.
|
@@ -47,4 +48,25 @@ def chat():
|
|
47 |
npc.remember_conversation(user_input, npc_reply)
|
48 |
npc.update_user_relationship(0.05) # ์์๋ก 0.05 ์์น (์ถํ ๊ฐ์ ๋ถ์ ๋ฑ์ผ๋ก ์กฐ์ )
|
49 |
|
50 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
28 |
[f"User: {m['user']}\n{npc_name}: {m['npc']}" for m in recent_memory]
|
29 |
)
|
30 |
|
31 |
+
# ํ๋กฌํํธ ๊ตฌ์ฑ
|
32 |
prompt = f"""
|
33 |
๋น์ ์ ์ด๋ฆ์ด {npc.name}์ธ ๊ฐ์์ ์บ๋ฆญํฐ์
๋๋ค.
|
34 |
๋น์ ์ ์ฑ๊ฒฉ์ "{npc.personality}"์
๋๋ค.
|
|
|
48 |
npc.remember_conversation(user_input, npc_reply)
|
49 |
npc.update_user_relationship(0.05) # ์์๋ก 0.05 ์์น (์ถํ ๊ฐ์ ๋ถ์ ๋ฑ์ผ๋ก ์กฐ์ )
|
50 |
|
51 |
+
# ๋ค๋ฅธ NPC์๊ฒ ์ ์ ์ ๋ํ ์ ๋ณด ์ ๋ฌ
|
52 |
+
for other_name, other_npc in npc_list.items():
|
53 |
+
if other_name != npc.name:
|
54 |
+
relation_score = npc.relationship_with_npcs.get(other_name, 0.0)
|
55 |
+
if relation_score > 0.5:
|
56 |
+
# ์ ์ ์ ๋ํ ์ธ์์ด ์ ๋ฌ๋จ
|
57 |
+
other_npc.update_user_relationship(0.02 * relation_score)
|
58 |
+
|
59 |
+
return jsonify({'response': npc_reply})
|
60 |
+
|
61 |
+
# npc ์ํ ์ ๋ณด
|
62 |
+
@npc_bp.route('/npc_info', methods=['GET'])
|
63 |
+
def npc_info():
|
64 |
+
npc_name = request.args.get('npc')
|
65 |
+
npc = npc_list[npc_name]
|
66 |
+
|
67 |
+
return jsonify({
|
68 |
+
"name":npc.name,
|
69 |
+
"personality": npc.personality,
|
70 |
+
"relationship_with_user": npc.relationship_with_user,
|
71 |
+
"relationship_with_npcs": npc.relationship_with_npcs
|
72 |
+
})
|
npc_social_network/static/js/npc_chat.js
CHANGED
@@ -3,7 +3,15 @@
|
|
3 |
async function sendMessage() {
|
4 |
const userMessage = document.getElementById("message").value;
|
5 |
const npc = document.getElementById("npc").value;
|
|
|
6 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
7 |
const response = await fetch('/npc_social_network/chat', {
|
8 |
method: 'POST',
|
9 |
headers: { 'Content-Type': 'application/json' },
|
@@ -11,6 +19,8 @@ async function sendMessage() {
|
|
11 |
});
|
12 |
|
13 |
const data = await response.json();
|
14 |
-
|
15 |
-
|
|
|
|
|
16 |
}
|
|
|
3 |
async function sendMessage() {
|
4 |
const userMessage = document.getElementById("message").value;
|
5 |
const npc = document.getElementById("npc").value;
|
6 |
+
const responseBox = document.getElementById("chatBox");
|
7 |
|
8 |
+
if (userMessage.trim() == "") return;
|
9 |
+
|
10 |
+
// UI์ ์ ์ ๋ฉ์์ง ์ถ๊ฐ
|
11 |
+
responseBox.innerHTML += `<div class = "chat-message"><span class="user">You:</span> ${userMessage}</div>`;
|
12 |
+
document.getElementById("message").value = "";
|
13 |
+
|
14 |
+
// ์๋ฒ์ ๋ฉ์์ง ์ ์ก
|
15 |
const response = await fetch('/npc_social_network/chat', {
|
16 |
method: 'POST',
|
17 |
headers: { 'Content-Type': 'application/json' },
|
|
|
19 |
});
|
20 |
|
21 |
const data = await response.json();
|
22 |
+
responseBox.innerHTML += `<div class="chat-message"><span class="npc">${npc}:</span> ${data.response}</div>`;
|
23 |
+
|
24 |
+
// ์คํฌ๋กค ํ๋จ ๊ณ ์
|
25 |
+
responseBox.scrollTop = responseBox.scrollHeight;
|
26 |
}
|
npc_social_network/templates/chat.html
CHANGED
@@ -1,21 +1,29 @@
|
|
1 |
<!-- portfolio/npc_social_network/templates/chat.html -->
|
2 |
<!DOCTYPE html>
|
3 |
-
<html lang="
|
4 |
<head>
|
5 |
<meta charset="UTF-8">
|
6 |
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
7 |
<title>NPC Chat</title>
|
|
|
|
|
8 |
</head>
|
9 |
<body>
|
10 |
-
<
|
11 |
-
|
12 |
-
|
13 |
-
<
|
14 |
-
<
|
15 |
-
|
16 |
-
|
17 |
-
|
|
|
|
|
|
|
|
|
18 |
<div id="chatBox"></div>
|
|
|
|
|
19 |
|
20 |
<script src="{{ url_for('npc_social.static', filename='js/npc_chat.js') }}"></script>
|
21 |
</body>
|
|
|
1 |
<!-- portfolio/npc_social_network/templates/chat.html -->
|
2 |
<!DOCTYPE html>
|
3 |
+
<html lang="ko">
|
4 |
<head>
|
5 |
<meta charset="UTF-8">
|
6 |
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
7 |
<title>NPC Chat</title>
|
8 |
+
|
9 |
+
<link rel="stylesheet" herf="{{ url_for('static', filename='style.css') }}"
|
10 |
</head>
|
11 |
<body>
|
12 |
+
<h2>NPC ์์
๋คํธ์ํฌ</h2>
|
13 |
+
|
14 |
+
<div class="meta-info">
|
15 |
+
<label for="npc"> ๋ํํ NPC: </label>
|
16 |
+
<select id = "npc" onchange="loadNPCInfo()">
|
17 |
+
<option>Alice</option>
|
18 |
+
<option>Bob</option>
|
19 |
+
<option>Charlie</option>
|
20 |
+
</select>
|
21 |
+
<span id="relationStatus" style="margin-left:20px";>๊ด๊ณ ์ ์: ๋ก๋ฉ ์ค...</span>
|
22 |
+
</div>
|
23 |
+
|
24 |
<div id="chatBox"></div>
|
25 |
+
<input type="text" id="message" placeholder="๋ฉ์ธ์ง๋ฅผ ์
๋ ฅํ์ธ์" style="width:80%">
|
26 |
+
<button onclick="sendMessage()">๋ณด๋ด๊ธฐ</button>
|
27 |
|
28 |
<script src="{{ url_for('npc_social.static', filename='js/npc_chat.js') }}"></script>
|
29 |
</body>
|