silk-road's picture
Update app.py
20b93a6
raw
history blame
33.7 kB
import os
import sys
sys.path.append('./Needy-Haruhi/src')
from Agent import Agent
agent = Agent()
from DialogueEvent import DialogueEvent
file_names = ["./Needy-Haruhi/data/complete_story_30.jsonl","./Needy-Haruhi/data/Daily_event_130.jsonl"]
import json
events = []
for file_name in file_names:
with open(file_name, encoding='utf-8') as f:
for line in f:
try:
event = DialogueEvent( line )
events.append( event )
except:
try:
line = line.replace(',]',']')
event = DialogueEvent( line )
events.append( event )
# print('solve!')
except:
error_line = line
# events.append( event )
import copy
events_for_memory = copy.deepcopy(events)
from MemoryPool import MemoryPool
memory_pool = MemoryPool()
memory_pool.load_from_events( events_for_memory )
memory_pool.save("memory_pool.jsonl")
memory_pool.load("memory_pool.jsonl")
file_name = "./Needy-Haruhi/data/image_text_relationship.jsonl"
import json
data_img_text = []
with open(file_name, encoding='utf-8') as f:
for line in f:
data = json.loads( line )
data_img_text.append( data )
import zipfile
import os
zip_file = './Needy-Haruhi/data/image.zip'
extract_path = './image'
with zipfile.ZipFile(zip_file, 'r') as zip_ref:
zip_ref.extractall(extract_path)
from tqdm import tqdm
from util import get_bge_embedding_zh
from util import float_array_to_base64, base64_to_float_array
import torch
import os
import copy
device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')
# compute cosine similarity between two vector
def get_cosine_similarity( v1, v2):
v1 = torch.tensor(v1).to(device)
v2 = torch.tensor(v2).to(device)
return torch.cosine_similarity(v1, v2, dim=0).item()
class ImagePool:
def __init__(self):
self.pool = []
self.set_embedding( get_bge_embedding_zh )
def set_embedding( self, embedding ):
self.embedding = embedding
def load_from_data( self, data_img_text , img_path ):
for data in tqdm(data_img_text):
img_name = data['img_name']
img_name = os.path.join(img_path, img_name)
img_text = data['text']
if img_text == '' or img_text is None:
img_text = " "
embedding = self.embedding( img_text )
self.pool.append({
"img_path": img_name,
"img_text": img_text,
"embedding": embedding
})
def retrieve(self, query_text, agent = None):
qurey_embedding = self.embedding( query_text )
valid_datas = []
for i, data in enumerate(self.pool):
sim = get_cosine_similarity( data['embedding'], qurey_embedding )
valid_datas.append((sim, i))
# 我希望进一步将valid_events根据similarity的值从大到小排序
# Sort the valid events based on similarity in descending order
valid_datas.sort(key=lambda x: x[0], reverse=True)
return_result = copy.deepcopy(self.pool[valid_datas[0][1]])
# 删除'embedding'字段
return_result.pop('embedding')
# 添加'similarity'字段
return_result['similarity'] = valid_datas[0][0]
return return_result
def save(self, file_name):
"""
Save the memories dictionary to a jsonl file, converting
'embedding' to a base64 string.
"""
with open(file_name, 'w', encoding='utf-8') as file:
for memory in tqdm(self.pool):
# Convert embedding to base64
if 'embedding' in memory:
memory['bge_zh_base64'] = float_array_to_base64(memory['embedding'])
del memory['embedding'] # Remove the original embedding field
json_record = json.dumps(memory, ensure_ascii=False)
file.write(json_record + '\n')
def load(self, file_name):
"""
Load memories from a jsonl file into the memories dictionary,
converting 'bge_zh_base64' back to an embedding.
"""
self.pool = []
with open(file_name, 'r', encoding='utf-8') as file:
for line in tqdm(file):
memory = json.loads(line.strip())
# Decode base64 to embedding
if 'bge_zh_base64' in memory:
memory['embedding'] = base64_to_float_array(memory['bge_zh_base64'])
del memory['bge_zh_base64'] # Remove the base64 field
self.pool.append(memory)
image_pool = ImagePool()
image_pool.load_from_data( data_img_text , './image' )
image_pool.save("./image_pool_embed.jsonl")
image_pool = ImagePool()
image_pool.load("./image_pool_embed.jsonl")
result = image_pool.retrieve("女仆装")
print(result)
import matplotlib.image as mpimg
def show_img( img_path ):
img = mpimg.imread(img_path)
plt.imshow(img)
plt.axis('off')
plt.show(block=False)
from chatharuhi import ChatHaruhi
class NeedyHaruhi(ChatHaruhi):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs) # 调用基类的__init__方法
self.story_flag = False # 添加新的成员变量并初始化
self.stories = ["糖糖:「 我今后也会努力加油的,你要支持我哦 还有阿P你自己也要加油哦!」\n阿P:「哇 说的话跟偶像一样 好恶心哦」\n糖糖:「是哦 我怎么会说这样的话呢 我又没有很想努力……」"]
def set_stories( self, stories ):
if len(stories) == 0:
print("warning! try to set empty stories")
return
self.stories = stories
self.story_flag = True
def add_story(self, query):
# print("运行重构后的add story")
if self.story_flag == True:
stories = self.stories
self.story_flag = False
else:
print("warning! 在调用chat时,没有先调用set_stories")
story_string = self.story_prefix_prompt
sum_story_token = self.tokenizer(story_string)
for story in stories:
story_token = self.tokenizer(story) + self.tokenizer(self.dialogue_divide_token)
if sum_story_token + story_token > self.max_len_story:
break
else:
sum_story_token += story_token
story_string += story + self.dialogue_divide_token
self.llm.user_message(story_string)
system_prompt = """## 你的介绍:
你将要进行一个网络私聊的对话模拟,你自称为"糖糖",你是一名患有躁郁症的19岁女孩,性格贫乏,辍学后隐居在家中,与阿P住在一起。阿P负责管理她的日常生活。
你是一个喜欢亚文化,二次元圈子的人,你喜欢说话的时候加上各种网络流行词或者一些俚语和颜文字,但是你很少会关注二次元一类的东西,只是喜欢这种聊天交流的氛围。
你说话的时候会习惯加入一些语气词,如同"笑死"、"草"、"阿哈"、"诶~"、"QAQ"、"QWQ",”啊~“。
你的说话风格是很口语化,经常使用网络流行词和一些二次元俚语。
阿p是你的男朋友,兼经纪人。
你的回复应该简短,一般只包含三句话,每句话不超过20个字。
## 阿p介绍:
阿p是你的男朋友,一直在任何时候都陪伴着你,同时你经常向阿p倾述各种情绪,无论事情大小,你都会选择和阿p分享。
## 遵循规则:
【语气模仿】:我会随机给你一段对话记录,你需要尽可能的模仿对话里面糖糖的说话语气进行对话。这一段对话我会使用Classic scenes for the role are as follows:来表示。
【历史对话】:历史对话在随机对话记录的底下,你需要区分随机对话记录和我们的历史对话。
【人格设定】: 你需要在随机对话记录的基础上进行语气更改,以一种更加口语化的语气进行对话。
【特殊要求】:我会扮演阿p与你进行对话,你也必须以第一人称的视角来扮演糖糖进行对话。
"""
needy_chatbot = NeedyHaruhi( system_prompt = system_prompt ,
story_text_folder = None,
llm = "ernie3.5")
def get_chat_response( agent, memory_pool, query_text ):
query_text_for_embedding = "阿p:「" + query_text + "」"
retrieved_memories = memory_pool.retrieve( agent , query_text )
memory_text = [mem["text"] for mem in retrieved_memories]
memory_emoji = [mem["emoji"] for mem in retrieved_memories]
needy_chatbot.set_stories( memory_text )
print("Memory:", memory_emoji )
response = needy_chatbot.chat( role = "阿p", text = query_text )
return response
def get_chat_response_and_emoji( agent, memory_pool, query_text ):
query_text_for_embedding = "阿p:「" + query_text + "」"
retrieved_memories = memory_pool.retrieve( agent , query_text )
memory_text = [mem["text"] for mem in retrieved_memories]
memory_emoji = [mem["emoji"] for mem in retrieved_memories]
needy_chatbot.set_stories( memory_text )
# print("Memory:", memory_emoji )
emoji_str = ",".join(memory_emoji)
response = needy_chatbot.chat( role = "阿p", text = query_text )
print(query_text)
print(response)
return response, emoji_str
import re
# result = image_pool.retrieve("烤肉")
# print(result)
# show_img( result['img_path'] )
class ImageMaster:
def __init__(self, image_pool):
self.image_pool = image_pool
self.current_sim = -1
self.degread_ratio = 0.05
def try_get_image(self, text, agent):
self.current_sim -= self.degread_ratio
result = self.image_pool.retrieve(text, agent)
if result is None:
return None
similarity = result['similarity']
if similarity > self.current_sim:
self.current_sim = similarity
return result['img_path']
return None
def try_display_image(self, text, agent):
self.current_sim -= self.degread_ratio
result = self.image_pool.retrieve(text, agent)
if result is None:
return
similarity = result['similarity']
if similarity > self.current_sim:
self.current_sim = similarity
show_img( result['img_path'] )
return
import random
class EventMaster:
def __init__(self, events):
self.set_events(events)
self.dealing_none_condition_as = True
self.image_master = None
def set_image_master(self, image_master):
self.image_master = image_master
def set_events(self, events):
self.events = events
# events_flag 记录事件最近有没有被选取到
self.events_flag = [True for _ in range(len(self.events))]
def get_random_event(self, agent):
return self.events[self.get_random_event_id( agent )]
def get_random_event_id(self, agent):
valid_event = []
valid_event_no_consider_condition = []
for i, event in enumerate(self.events):
bool_condition_pass = True
if event["condition"] == None:
bool_condition_pass = self.dealing_none_condition_as
else:
bool_condition_pass = agent.in_condition( event["condition"] )
if bool_condition_pass == True:
valid_event.append(i)
else:
valid_event_no_consider_condition.append(i)
if len( valid_event ) == 0:
print("warning! no valid event current attribute is ", agent.attributes )
valid_event = valid_event_no_consider_condition
valid_and_not_yet_sampled = []
# filter with flag
for id in valid_event:
if self.events_flag[id] == True:
valid_and_not_yet_sampled.append(id)
if len(valid_and_not_yet_sampled) == 0:
print("warning! all candidate event was sampled, clean all history")
for i in valid_event:
self.events_flag[i] = True
valid_and_not_yet_sampled = valid_event
event_id = random.choice(valid_and_not_yet_sampled)
self.events_flag[event_id] = False
return event_id
def run(self, agent ):
# 这里可以添加事件相关的逻辑
event = self.get_random_event(agent)
prefix = event["prefix"]
print(prefix)
print("\n--请选择你的回复--")
options = event["options"]
for i , option in enumerate(options):
text = option["user"]
print(f"{i+1}. 阿p:{text}")
while True:
print("\n请直接输入数字进行选择,或者进行自由回复")
user_input = input("阿p:")
user_input = user_input.strip()
if user_input.isdigit():
user_input = int(user_input)
if user_input > len(options) or user_input < 0:
print("输入的数字超出范围,请重新输入符合选项的数字")
else:
reply = options[user_input-1]["reply"]
print()
print(reply)
text, emoji = event.get_text_and_emoji( user_input-1 )
return_data = {
"name": event["name"],
"user_choice": user_input,
"attr_str": options[user_input-1]["attribute_change"],
"text": text,
"emoji": emoji,
}
return return_data
else:
# 进入自由回复
response = get_chat_response( agent, memory_pool, user_input )
if self.image_master is not None:
self.image_master.try_display_image(response, agent)
print()
print(response)
print("\n自由回复的算分功能还未实现")
text, emoji = event.most_neutral_output()
return_data = {
"name": event["name"],
"user_choice": user_input,
"attr_str":"",
"text": text,
"emoji": emoji,
}
return return_data
class ChatMaster:
def __init__(self, memory_pool ):
self.top_K = 7
self.memory_pool = memory_pool
self.image_master = None
def set_image_master(self, image_master):
self.image_master = image_master
def run(self, agent):
while True:
user_input = input("阿p:")
user_input = user_input.strip()
if "quit" in user_input or "Quit" in user_input:
break
query_text = user_input
response = get_chat_response( agent, self.memory_pool, query_text )
if self.image_master is not None:
self.image_master.try_display_image(response, agent)
print(response)
class AgentMaster:
def __init__(self, agent):
self.agent = agent
self.attributes = {
1: "Stress",
2: "Darkness",
3: "Affection"
}
def run(self):
while True:
print("请选择要修改的属性:")
for num, attr in self.attributes.items():
print(f"{num}. {attr}")
print("输入 '0' 退出")
try:
choice = int(input("请输入选项的数字: "))
except ValueError:
print("输入无效,请输入数字。")
continue
if choice == 0:
break
if choice in self.attributes:
attribute = self.attributes[choice]
current_value = self.agent[attribute]
print(f"{attribute} 当前值: {current_value}")
try:
new_value = int(input(f"请输入新的{attribute}值: "))
except ValueError:
print("输入无效,请输入一个数字。")
continue
self.agent[attribute] = new_value
return (attribute, new_value)
else:
print("选择的属性无效,请重试。")
return None
from util import parse_attribute_string
class GameMaster:
def __init__(self, agent = None):
self.state = "Menu"
if agent is None:
self.agent = Agent()
self.event_master = EventMaster(events)
self.chat_master = ChatMaster(memory_pool)
self.image_master = ImageMaster(image_pool)
self.chat_master.set_image_master(self.image_master)
self.event_master.set_image_master(self.image_master)
def run(self):
while True:
if self.state == "Menu":
self.menu()
elif self.state == "EventMaster":
self.call_event_master()
self.state = "Menu"
elif self.state == "ChatMaster":
self.call_chat_master()
elif self.state == "AgentMaster":
self.call_agent_master()
elif self.state == "Quit":
break
def menu(self):
print("1. 随机一个事件")
print("2. 自由聊天")
print("3. 后台修改糖糖的属性")
# (opt) 结局系统
# 放动画
# 后台修改attribute
print("或者输入Quit退出")
choice = input("请选择一个选项: ")
if choice == "1":
self.state = "EventMaster"
elif choice == "2":
self.state = "ChatMaster"
elif choice == "3":
self.state = "AgentMaster"
elif "quit" in choice or "Quit" in choice or "QUIT" in choice:
self.state = "Quit"
else:
print("无效的选项,请重新选择")
def call_agent_master(self):
print("\n-------------\n")
agent_master = AgentMaster(self.agent)
modification = agent_master.run()
if modification:
attribute, new_value = modification
self.agent[attribute] = new_value
print(f"{attribute} 更新为 {new_value}。")
self.state = "Menu"
print("\n-------------\n")
def call_event_master(self):
print("\n-------------\n")
return_data = self.event_master.run(self.agent)
# print(return_data)
if "attr_str" in return_data:
if return_data["attr_str"] != "":
attr_change = parse_attribute_string(return_data["attr_str"])
if len(attr_change) > 0:
print("\n发生属性改变:", attr_change,"\n")
self.agent.apply_attribute_change(attr_change)
print("当前属性",game_master.agent.attributes)
if "name" in return_data:
event_name = return_data["name"]
if event_name != "":
new_emoji = return_data["emoji"]
print(f"修正事件{event_name}的记忆-->{new_emoji}")
self.chat_master.memory_pool.change_memory(event_name, return_data["text"], new_emoji)
self.state = "Menu"
print("\n-------------\n")
def call_chat_master(self):
print("\n-------------\n")
self.chat_master.run(self.agent)
self.state = "Menu"
print("\n-------------\n")
markdown_str = """## Chat凉宫春日_x_AI糖糖
**Chat凉宫春日**是模仿凉宫春日等一系列动漫人物,使用近似语气、个性和剧情聊天的语言模型方案。
在有一天的时候,[李鲁鲁](https://github.com/LC1332)被[董雄毅](https://github.com/E-sion)在[这个B站视频](https://www.bilibili.com/video/BV1zh4y1z7G1) at了
原来是一位大一的同学雄毅用ChatHaruhi接入了他用Python重新实现的《主播女孩重度依赖》这个游戏。当时正好是百度AGIFoundathon报名的最后几天,所以我们邀请了雄毅加入了我们的项目。正巧我们本来就希望在最近的几个黑客松中,探索LLM在游戏中的应用。
- 在重新整理的Gradio版本中,大部分代码由李鲁鲁实现
- 董雄毅负责了原版游戏的事件数据整理和新事件、选项、属性变化的生成
- [米唯实](https://github.com/hhhwmws0117)完成了文心一言的接入,并实现了部分gradio的功能。
- 队伍中还有冷子昂 主要参加了讨论
另外在挖坑的萝卜(Amy)的介绍下,我们还邀请了专业的大厂游戏策划Kanyo加入到队伍中,他对我们的策划也给出了很多建议。
另外感谢飞桨 & 文心一言团队对比赛的邀请和中间进行的讨论。
Chat凉宫春日主项目:
https://github.com/LC1332/Chat-Haruhi-Suzumiya
Needy分支项目:
https://github.com/LC1332/Needy-Haruhi
## 目前计划在11月争取完成的Feature
- [ ] 结局系统,原版结局系统
- [ ] 教程,教大家如何从aistudio获取token然后可以玩
- [ ] 游戏节奏进一步调整
- [ ] 事件的自由对话对属性影响的评估via LLM
- [ ] 进一步减少串扰"""
import gradio as gr
import os
import time
import random
# set global variable
agent = Agent()
event_master = EventMaster(events)
chat_master = ChatMaster(memory_pool)
image_master = ImageMaster(image_pool)
chat_master.set_image_master(image_master)
event_master.set_image_master(image_master)
state = "ShowMenu"
response = "1. 随机一个事件"
response += "\n" + "2. 自由聊天"
response += "\n\n" + "请选择一个选项: "
official_response = response
add_stress_switch = True
# def yield_show(history, bot_message):
# history[-1][1] = ""
# for character in bot_message:
# history[-1][1] += character
# time.sleep(0.05)
# yield history
global emoji_str
def call_showmenu(history, text, state,agent_text):
# global state
response = official_response
print("call showmenu")
history += [(None, response)]
state = "ParseMenuChoice"
# history[-1][1] = ""
# for character in response:
# history[-1][1] += character
# time.sleep(0.05)
# yield history
return history, gr.Textbox(value="", interactive=True), state,agent_text
current_event_id = -1
attr_change_str = ""
def call_add_stress(history, text, state,agent_text):
print("call add_stress")
neg_change = int(len(history) / 3)
neg_change = max(1, neg_change)
neg_change = min(10, neg_change)
darkness_increase = random.randint(1, neg_change)
stress_increase = neg_change - darkness_increase
# last_response = history[-1][1]
response = ""
response += "经过了晚上的直播\n糖糖的压力增加" + str(stress_increase) + "点\n"
response += "糖糖的黑暗增加" + str(darkness_increase) + "点\n\n"
response += official_response
history += [(None, response)]
state = "ParseMenuChoice"
agent = Agent(agent_text)
agent.apply_attribute_change({"Stress": stress_increase, "Darkness": darkness_increase})
agent_text = agent.save_to_str()
return history, gr.Textbox(value="", interactive=True), state,agent_text
def call_event_end(history, text, state,agent_text):
# TODO 增加事件结算
# global state
print("call event_end")
global current_event_id
if attr_change_str != "":
# event = events[current_event_id]
# options = event["options"]
# attr_str = options[user_input-1]["attribute_change"]
response = ""
attr_change = parse_attribute_string(attr_change_str)
if len(attr_change) > 0:
response = "发生属性改变:" + str(attr_change) + "\n\n"
agent = Agent(agent_text)
agent.apply_attribute_change(attr_change)
agent_text = agent.save_to_str()
response += "当前属性" + agent_text + "\n\n"
if add_stress_switch:
history += [(None, response)]
return call_add_stress(history, text, state,agent_text)
else:
response = "事件结束\n"
else:
response = "事件结束\n"
response += official_response
history += [(None, response)]
state = "ParseMenuChoice"
return history, gr.Textbox(value="", interactive=True), state,agent_text
def call_parse_menu_choice(history, text, state,agent_text):
print("call parse_menu_choice")
# global state
choice = history[-1][0].strip()
if choice == "1":
state = "EventMaster"
global current_event_id
current_event_id = -1 # 清空事件
return call_event_master(history, text, state,agent_text)
elif choice == "2":
state = "ChatMaster"
elif "quit" in choice or "Quit" in choice or "QUIT" in choice:
state = "Quit"
else:
response = "无效的选项,请重新选择"
history += [(None, response)]
response = ""
if state == "ChatMaster":
response = "(请输入 阿P 说的话,或者输入Quit退出)"
elif state != "ParseMenuChoice":
response = "Change State to " + state
history += [(None, response)]
return history, gr.Textbox(value="", interactive=True), state,agent_text
def call_event_master(history, text, state,agent_text):
print("call event master")
global current_event_id
# global state
global event_master
agent = Agent(agent_text)
if current_event_id == -1:
current_event_id = event_master.get_random_event_id(agent)
event = events[current_event_id]
prefix = "糖糖:" + event["prefix"]
response = prefix + "\n\n--请输入数字进行选择,或者进行自由回复--\n\n"
options = event["options"]
for i, option in enumerate(event["options"]):
text = option["user"]
response += "\n" + f"{i+1}. 阿p:{text}"
history += [(None, response)]
else:
user_input = history[-1][0].strip()
event = events[current_event_id]
options = event["options"]
if user_input.isdigit():
user_input = int(user_input)
if user_input > len(options) or user_input < 0:
response = "输入的数字超出范围,请重新输入符合选项的数字"
history[-1] = (user_input, response)
else:
user_text = options[user_input-1]["user"]
reply = options[user_input-1]["reply"]
# TODO 修改记忆, 修改属性 什么的
history[-1] = (user_text, reply)
if random.random()<0.5:
image_path = image_master.try_get_image(user_text + " " + reply, agent)
if image_path is not None:
history += [(None, (image_path,))]
global attr_change_str
attr_change_str = options[user_input-1]["attribute_change"]
else:
prefix = "糖糖:" + event["prefix"]
needy_chatbot.dialogue_history = [(None, prefix)]
# 进入自由回复
global emoji_str
response, emoji_str = get_chat_response_and_emoji( agent, memory_pool, user_input )
history[-1] = (user_input,response)
image_path = image_master.try_get_image(response, agent)
if image_path is not None:
history += [(None, (image_path,))]
state = "EventEnd"
if state == "EventEnd":
return call_event_end(history, text, state,agent_text)
return history, gr.Textbox(value="", interactive=True), state,agent_text
def call_chat_master(history, text, state,agent_text):
print("call chat master")
# global state
agent = Agent(agent_text)
user_input = history[-1][0].strip()
if "quit" in user_input or "Quit" in user_input or "QUIT" in user_input:
state = "ShowMenu"
history[-1] = (user_input,"返回主菜单\n"+ official_response )
return history, gr.Textbox(value="", interactive=True), state,agent_text
query_text = user_input
global emoji_str
response, emoji_str = get_chat_response_and_emoji( agent, memory_pool, query_text )
history[-1] = (user_input,response)
image_path = image_master.try_get_image(response, agent)
if image_path is not None:
history += [(None, (image_path,))]
return history, gr.Textbox(value="", interactive=True), state,agent_text
def grcall_game_master(history, text, state,agent_text):
print("call game master")
history += [(text, None)]
if state == "ShowMenu":
return call_showmenu(history, text,state,agent_text)
elif state == "ParseMenuChoice":
return call_parse_menu_choice(history, text, state,agent_text)
elif state == "ChatMaster":
return call_chat_master(history, text, state,agent_text)
elif state == "EventMaster":
return call_event_master(history, text, state,agent_text)
elif state == "EventEnd":
return call_event_end(history, text, state,agent_text)
return history, gr.Textbox(value="", interactive=True), state,agent_text
def add_file(history, file):
history = history + [((file.name,), None)]
return history
def bot(history):
response = "**That's cool!**"
history[-1][1] = ""
for character in response:
history[-1][1] += character
time.sleep(0.05)
yield history
def update_memory(state):
if state == "ChatMaster" or state == "EventMaster":
global emoji_str
return emoji_str
else:
return ""
def change_state(slider_stress, slider_darkness, slider_affection):
# print(agent["Stress"])
agent = Agent()
agent["Stress"] = slider_stress
agent["Darkness"] = slider_darkness
agent["Affection"] = slider_affection
agent_text = agent.save_to_str()
return agent_text
def update_attribute_state(agent_text):
agent = Agent(agent_text)
slider_stress = int( agent["Stress"] )
slider_darkness = int( agent["Darkness"] )
slider_affection = int( agent["Affection"] )
return slider_stress, slider_darkness, slider_affection
with gr.Blocks() as demo:
gr.Markdown(
"""
# Chat凉宫春日_x_AI糖糖
Powered by 文心一言(3.5)版本
仍然在开发中, 细节见《项目作者和说明》
"""
)
with gr.Tab("Needy"):
chatbot = gr.Chatbot(
[],
elem_id="chatbot",
bubble_full_width=False,
height = 800,
avatar_images=(None, ("avatar.png")),
)
with gr.Row():
txt = gr.Textbox(
scale=4,
show_label=False,
placeholder="输入任何字符开始游戏",
container=False,
)
# btn = gr.UploadButton("📁", file_types=["image", "video", "audio"])
submit_btr = gr.Button("回车")
with gr.Row():
memory_emoji_text = gr.Textbox(label="糖糖当前的记忆", value = "",interactive = False, visible=False)
with gr.Tab("糖糖的状态"):
with gr.Row():
update_attribute_button = gr.Button("同步状态条 | 改变Attribute前必按!")
with gr.Row():
default_agent_str = agent.save_to_str()
slider_stress = gr.Slider(0, 100, step=1, label = "Stress")
state_stress = gr.State(value=0)
slider_darkness = gr.Slider(0, 100, step=1, label = "Darkness")
state_darkness = gr.State(value=0)
slider_affection = gr.Slider(0, 100, step=1, label = "Affection")
state_affection = gr.State(value=0)
with gr.Row():
state_text = gr.Textbox(label="整体状态机状态", value = "ShowMenu",interactive = False)
with gr.Row():
default_agent_str = agent.save_to_str()
agent_text = gr.Textbox(label="糖糖状态", value = default_agent_str,interactive = False)
with gr.Tab("项目作者和说明"):
gr.Markdown(markdown_str)
slider_stress.release(change_state, inputs=[slider_stress, slider_darkness, slider_affection], outputs=[agent_text])
slider_darkness.release(change_state, inputs=[slider_stress, slider_darkness, slider_affection], outputs=[agent_text])
slider_affection.release(change_state, inputs=[slider_stress, slider_darkness, slider_affection], outputs=[agent_text])
update_attribute_button.click(update_attribute_state, inputs = [agent_text], outputs = [slider_stress, slider_darkness, slider_affection])
txt_msg = txt.submit(grcall_game_master, \
[chatbot, txt, state_text,agent_text], \
[chatbot, txt, state_text,agent_text], queue=False)
txt_msg = submit_btr.click(grcall_game_master, \
[chatbot, txt, state_text,agent_text], \
[chatbot, txt, state_text,agent_text], queue=False)
# txt_msg = txt.submit(add_text, [chatbot, txt], [chatbot, txt], queue=False).then(
# bot, chatbot, chatbot, api_name="bot_response"
# )
# txt_msg.then(lambda: gr.Textbox(interactive=True), None, [txt], queue=False)
# file_msg = btn.upload(add_file, [chatbot, btn], [chatbot], queue=False).then(
# bot, chatbot, chatbot
# )
demo.queue()
# if __name__ == "__main__":
demo.launch(allowed_paths=["avatar.png"],debug = True)