Skip to content

Commit

Permalink
添加提示词功能,支持角色扮演
Browse files Browse the repository at this point in the history
  • Loading branch information
NingNing0111 committed May 5, 2024
1 parent 8643c5e commit 60926a6
Show file tree
Hide file tree
Showing 14 changed files with 905 additions and 186 deletions.
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@

- 流式输出响应,体验极佳;
- 支持 Markdown 渲染、代码高亮、Latex 渲染;
- 100+中文提示词,玩转 GPT 角色扮演;
- 支持一键复制代码;
- 支持对话模型微调;
- 国际化,支持中英文;
Expand All @@ -17,6 +18,7 @@
| :--------: | :---------------------------------: | :--------------------------------: |
| 对话 | ![](doc/images/chat_light.jpg) | ![](doc/images/chat_dark.jpg) |
| 图片生成 | ![](doc/images/imageChat_light.jpg) | ![](doc/images/imageChat_dark.jpg) |
| 100+提示词 | ![](doc/images/roles_light.jpg) | ![](doc/images/roles_dark.jpg) |
| 代码高亮 | ![](doc/images/highlight_light.jpg) | ![](doc/images/highlight_dark.jpg) |
| Latex 渲染 | ![](doc/images/latex_light.jpg) | ![](doc/images/latex_dark.jpg) |
| 设置页面 | ![](doc/images/setting_light.jpg) | ![](doc/images/setting_dark.jpg) |
Expand Down
Binary file added doc/images/roles_dark.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added doc/images/roles_light.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
59 changes: 59 additions & 0 deletions lib/component/role_home.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@

import 'package:adaptive_theme/adaptive_theme.dart';
import 'package:chat_all/config/prompts.dart';
import 'package:flutter/material.dart';

class RoleHome extends StatelessWidget {
final Function(String prompt) setPrompt;
const RoleHome({super.key,required this.setPrompt});

@override
Widget build(BuildContext context) {

return ListView.builder(
itemBuilder: (context, index) => GestureDetector(
onTap: (){
setPrompt(promptsCN[index]['prompt']!);
},
child: Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(15),
border: Border.all(color: Colors.grey),
),
padding: const EdgeInsets.all(5),
margin: const EdgeInsets.only(left: 10, right: 10, top: 5, bottom: 5),
child: Row(
children: [
emojis[index],
const SizedBox(width: 10,),
Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.center,
children: [
SizedBox(
width: 260,
child: Text(
promptsCN[index]["act"]!,
style: AdaptiveTheme.of(context).theme.textTheme.titleLarge,
overflow: TextOverflow.ellipsis,
),
),
// Text("你好")
SizedBox(
width: 260,
child: Text(
promptsCN[index]['prompt']!,
style:
AdaptiveTheme.of(context).theme.textTheme.titleMedium,
overflow: TextOverflow.ellipsis,
))
],
)
],
),
),
),
itemCount: promptsCN.length,
);
}
}
779 changes: 648 additions & 131 deletions lib/config/prompts.dart

Large diffs are not rendered by default.

3 changes: 3 additions & 0 deletions lib/config/router/router.dart
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import 'package:chat_all/component/role_home.dart';
import 'package:chat_all/controller/setting.dart';
import 'package:chat_all/page/chat.dart';
import 'package:chat_all/page/roles.dart';
import 'package:chat_all/page/setting.dart';
import 'package:chat_all/page/unknow.dart';
import 'package:get/get.dart';
Expand All @@ -12,5 +14,6 @@ final routers = [
name: "/setting",
page: () => const SettingPage(),
binding: SettingControllerBinding()),
GetPage(name: "/roles", page: ()=>const RolesPage()),
GetPage(name: "/unknown", page: () => const UnknownPage())
];
2 changes: 0 additions & 2 deletions lib/controller/chat.dart
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ import '../model/message.dart';

class ChatPageController extends GetxController {
HistoryMessage currHistoryMessage = Get.find<SidebarPageController>().histories.last;

void updateMessageContent(int index, String content) {
currHistoryMessage.messages[index].content = content;
update();
Expand All @@ -29,6 +28,5 @@ class ChatPageController extends GetxController {
void onClose() {
Get.find<SidebarPageController>().saveAll();
super.onClose();

}
}
2 changes: 1 addition & 1 deletion lib/main.dart
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ class MyApp extends StatelessWidget {
initialRoute: "/",
getPages: routers,
unknownRoute: routers.last,
defaultTransition: Transition.rightToLeft,
defaultTransition: Transition.fadeIn,
home: const ChatPage()));
}
}
41 changes: 32 additions & 9 deletions lib/page/chat.dart
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import 'dart:developer';
import 'dart:ffi';

import 'package:adaptive_theme/adaptive_theme.dart';
import 'package:chat_all/component/chat_home.dart';
Expand Down Expand Up @@ -43,8 +44,6 @@ class _ChatPageState extends State<ChatPage> {
super.dispose();
}



@override
Widget build(BuildContext context) {
return Scaffold(
Expand Down Expand Up @@ -148,7 +147,6 @@ class _ChatPageState extends State<ChatPage> {
child: currMessage.content.isEmpty
? const CircularProgressIndicator(
backgroundColor: Colors.blue,

)
: MdCodeMath(currMessage.content),
),
Expand Down Expand Up @@ -198,10 +196,14 @@ class _ChatPageState extends State<ChatPage> {
}

Future<void> sendMessage(String prompt) async {
if (_chatController.currHistoryMessage.messages.isEmpty) {
if (_chatController.currHistoryMessage.messages.isEmpty ||
(_chatController.currHistoryMessage.messages.length == 1 &&
_chatController.currHistoryMessage.messages.first.role ==
OpenAIChatMessageRole.system)) {
_chatController.currHistoryMessage.title = prompt;
_sidebarController.updateHistory(_chatController.currHistoryMessage);
}

_chatController.addMessage(Message(
content: prompt,
role: OpenAIChatMessageRole.user,
Expand Down Expand Up @@ -247,16 +249,37 @@ class _ChatPageState extends State<ChatPage> {
);
}

// 限制消息列表的最大长度
// 构建请求对话消息列表
// 当关闭提示词注入时,消息列表头部不存在system
// 开启时,消息列表头部始终有system
List<Message> getChatMessageByLen() {
// message 列表
final chatMessage = _chatController.currHistoryMessage.messages;
final originMessages = _chatController.currHistoryMessage.messages;
// 拷贝一份
var chatMessage = List.of(originMessages);
// 截取请求消息
// 长度、最大长度
final len = chatMessage.length;
final maxLen = _settingController.historyLength.value;
if (len > maxLen) {
return chatMessage.sublist(len - maxLen);
// 普通对话时,消息列表中的头部不是system
if (originMessages.first.role != OpenAIChatMessageRole.system) {
if (len > maxLen) {
chatMessage = chatMessage.sublist(len - maxLen);
}
} else {
// 获取系统提示词
Message system = originMessages.first;
if (len > maxLen) {
chatMessage = chatMessage.sublist(len - maxLen);
}
if (chatMessage.first.role == OpenAIChatMessageRole.system) {
chatMessage.removeAt(0);
}
// 根据是否开启系统词注入进行注入
if (_settingController.enabledSystemPrompt.value) {
chatMessage.insert(0, system);
}
}

return chatMessage;
}
}
49 changes: 49 additions & 0 deletions lib/page/roles.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
import 'dart:developer';

import 'package:adaptive_theme/adaptive_theme.dart';
import 'package:chat_all/component/role_home.dart';
import 'package:chat_all/model/message.dart';
import 'package:dart_openai/dart_openai.dart';
import 'package:flutter/material.dart';
import 'package:get/get.dart';

import '../controller/chat.dart';
import '../controller/sidebar.dart';

class RolesPage extends StatefulWidget {
const RolesPage({super.key});

@override
State<StatefulWidget> createState() => _RolesPageState();

}

class _RolesPageState extends State<RolesPage>{
final _sidebarController = Get.find<SidebarPageController>();
final _chatController = Get.find<ChatPageController>();


@override
Widget build(BuildContext context) {
return Scaffold(

appBar: AppBar(
title: const Text("角色列表"),
centerTitle: true,
backgroundColor: AdaptiveTheme.of(context).theme.primaryColor,
),
body: RoleHome(setPrompt: setPrompt,),
);
}

void setPrompt(String prompt){

_sidebarController.newHistory();
_chatController.reloadHistory();
_chatController.currHistoryMessage.messages.add(
Message(content: prompt, role: OpenAIChatMessageRole.system, historyId: _chatController.currHistoryMessage.id)
);
Get.toNamed("/chat");
}

}
78 changes: 69 additions & 9 deletions lib/page/sidebar.dart
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import 'package:adaptive_theme/adaptive_theme.dart';
import 'package:chat_all/component/role_home.dart';
import 'package:chat_all/controller/chat.dart';
import 'package:chat_all/controller/sidebar.dart';
import 'package:chat_all/service/assets.dart';
Expand Down Expand Up @@ -29,9 +30,8 @@ class _SidebarPageState extends State<SidebarPage> {
mainAxisAlignment: MainAxisAlignment.start,
children: [
GestureDetector(
onTap: () {
_sidebarPageController.newHistory();
_chatController.reloadHistory();
onTap: (){
_createNewChat();
},
child: Container(
decoration: BoxDecoration(
Expand Down Expand Up @@ -80,17 +80,16 @@ class _SidebarPageState extends State<SidebarPage> {
final currHistory =
_sidebarPageController.histories[len - index - 1];
return Container(
margin:
const EdgeInsets.only(left: 10, right: 10, top: 10),
margin: const EdgeInsets.only(left: 10, right: 10, top: 10),
padding: const EdgeInsets.all(5),
height: 100,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(10),
border: _sidebarPageController.choice.value == index
? Border.all(
color: const Color(0xff4691a8), width: 2)
color: const Color(0xff4691a8), width: 2)
: Border.all(
color: const Color(0x304691a8), width: 1)),
color: const Color(0x304691a8), width: 1)),
child: Column(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Expand Down Expand Up @@ -119,8 +118,7 @@ class _SidebarPageState extends State<SidebarPage> {
_sidebarPageController
.deleteHistory(len - index - 1);
_chatController.setHistory(
_sidebarPageController
.histories.last);
_sidebarPageController.histories.last);
_sidebarPageController.setChoice(0);
},
icon: const Icon(
Expand Down Expand Up @@ -180,4 +178,66 @@ class _SidebarPageState extends State<SidebarPage> {
]),
);
}

void _createNewChat() {
Get.defaultDialog(
title: "选择角色",
titlePadding: const EdgeInsets.all(5),
content: Column(
children: [
Text(
"是否选择一个角色进行对话",
style: AdaptiveTheme.of(context)
.theme
.textTheme
.titleLarge,
),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
TextButton(
onPressed: () {
_toChat();
},
child: Container(
padding: const EdgeInsets.all(5),
decoration: BoxDecoration(
color: Colors.cyan,
borderRadius: BorderRadius.circular(15)
),
child: const Text(
"直接开始",
style: TextStyle(fontSize: 16,color: Colors.white)
),
)),
TextButton(
onPressed: () {
_chooseRole();
},
child: Container(
decoration: BoxDecoration(
color: const Color(0xff4691a8),
borderRadius: BorderRadius.circular(15)),
padding: const EdgeInsets.all(5),
child: const Text(
"选择角色",
style: TextStyle(
fontSize: 16, color: Colors.white),
),
))
],
)
],
));
}

void _toChat() {
_sidebarPageController.newHistory();
_chatController.reloadHistory();
Get.back();
}

void _chooseRole(){
Get.toNamed("/roles");
}
}
Loading

0 comments on commit 60926a6

Please sign in to comment.