- add system prompt
- add new deepseek r1 model - fix stream builder - show streaming complete check
This commit is contained in:
@@ -36,7 +36,7 @@ class _AiChatState extends State<AiChat> {
|
|||||||
late types.User _user;
|
late types.User _user;
|
||||||
late types.User _mihAI;
|
late types.User _mihAI;
|
||||||
String systemPromt =
|
String systemPromt =
|
||||||
"You are a helpful and friendly AI assistant. You are running on a system called MIH which was created by \"Mzansi Innovation Hub\" a South African based company.";
|
"You are a helpful and friendly AI assistant. You are running on a system called 'MIH' which was created by 'Mzansi Innovation Hub' a South African based company. The name we have given you is 'Mzansi Ai'. Please keep your thinking to a few paragraphs and your answer to one short paragraph.";
|
||||||
bool _aiThinking = false;
|
bool _aiThinking = false;
|
||||||
final client = ollama.OllamaClient(
|
final client = ollama.OllamaClient(
|
||||||
baseUrl: "${AppEnviroment.baseAiUrl}/api",
|
baseUrl: "${AppEnviroment.baseAiUrl}/api",
|
||||||
@@ -50,6 +50,17 @@ class _AiChatState extends State<AiChat> {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void _loadMessages() async {
|
||||||
|
final response = await rootBundle.loadString('assets/messages.json');
|
||||||
|
final messages = (jsonDecode(response) as List)
|
||||||
|
.map((e) => types.Message.fromJson(e as Map<String, dynamic>))
|
||||||
|
.toList();
|
||||||
|
|
||||||
|
setState(() {
|
||||||
|
_messages = messages;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
void _handleSendPressed(types.PartialText message) {
|
void _handleSendPressed(types.PartialText message) {
|
||||||
final textMessage = types.TextMessage(
|
final textMessage = types.TextMessage(
|
||||||
author: _user,
|
author: _user,
|
||||||
@@ -94,13 +105,9 @@ class _AiChatState extends State<AiChat> {
|
|||||||
|
|
||||||
Widget responseWindow(
|
Widget responseWindow(
|
||||||
Stream<String> aiChatStream,
|
Stream<String> aiChatStream,
|
||||||
// StreamSubscription<String> aiChatSubscription,
|
|
||||||
) {
|
) {
|
||||||
StreamSubscription<String> aiChatSubscription =
|
|
||||||
aiChatStream.listen((response) {});
|
|
||||||
types.TextMessage textMessage;
|
|
||||||
return StreamBuilder(
|
return StreamBuilder(
|
||||||
stream: _generateChatCompletionWithHistoryStream("", client),
|
stream: aiChatStream,
|
||||||
builder: (context, snapshot) {
|
builder: (context, snapshot) {
|
||||||
if (snapshot.hasData) {
|
if (snapshot.hasData) {
|
||||||
return MihAppWindow(
|
return MihAppWindow(
|
||||||
@@ -108,80 +115,62 @@ class _AiChatState extends State<AiChat> {
|
|||||||
windowTitle: 'Mzansi AI Thoughts',
|
windowTitle: 'Mzansi AI Thoughts',
|
||||||
windowTools: const [],
|
windowTools: const [],
|
||||||
onWindowTapClose: () {
|
onWindowTapClose: () {
|
||||||
if (_aiThinking) {
|
_captureAIResponse(snapshot.requireData);
|
||||||
aiChatSubscription.cancel();
|
|
||||||
}
|
|
||||||
setState(() {
|
|
||||||
_chatHistory.add(
|
|
||||||
ollama.Message(
|
|
||||||
role: ollama.MessageRole.assistant,
|
|
||||||
content: snapshot.requireData,
|
|
||||||
),
|
|
||||||
);
|
|
||||||
});
|
|
||||||
textMessage = types.TextMessage(
|
|
||||||
author: _mihAI,
|
|
||||||
createdAt: DateTime.now().millisecondsSinceEpoch,
|
|
||||||
id: const Uuid().v4(),
|
|
||||||
// metadata: <String, dynamic>{
|
|
||||||
// "thoughts": snapshot.requireData
|
|
||||||
// },
|
|
||||||
text: snapshot.requireData
|
|
||||||
.replaceAll("<think>\n\n", "Thinking:\n")
|
|
||||||
.replaceAll("<think>\n", "Thinking:\n")
|
|
||||||
.replaceAll("</think>\n\n", "Answer:\n"), //message.text,
|
|
||||||
);
|
|
||||||
|
|
||||||
_addMessage(textMessage);
|
|
||||||
Navigator.of(context).pop();
|
Navigator.of(context).pop();
|
||||||
},
|
},
|
||||||
windowBody: [
|
windowBody: [
|
||||||
Text(
|
Stack(
|
||||||
snapshot.requireData,
|
children: [
|
||||||
textAlign: TextAlign.left,
|
Text(
|
||||||
style: TextStyle(
|
snapshot.requireData,
|
||||||
color:
|
textAlign: TextAlign.left,
|
||||||
MzanziInnovationHub.of(context)!.theme.secondaryColor(),
|
style: TextStyle(
|
||||||
fontSize: _chatFrontSize,
|
color: MzanziInnovationHub.of(context)!
|
||||||
fontWeight: FontWeight.bold,
|
.theme
|
||||||
),
|
.secondaryColor(),
|
||||||
),
|
fontSize: _chatFrontSize,
|
||||||
const SizedBox(height: 15),
|
fontWeight: FontWeight.bold,
|
||||||
Visibility(
|
),
|
||||||
visible: _aiThinking == false,
|
),
|
||||||
child: MIHButton(
|
Positioned(
|
||||||
onTap: () {
|
bottom: 0,
|
||||||
setState(() {
|
right: 0,
|
||||||
_chatHistory.add(
|
child: Visibility(
|
||||||
ollama.Message(
|
visible: _aiThinking == false,
|
||||||
role: ollama.MessageRole.assistant,
|
child: IconButton.filled(
|
||||||
content: snapshot.requireData,
|
iconSize: 25,
|
||||||
|
autofocus: true,
|
||||||
|
onPressed: () {
|
||||||
|
_captureAIResponse(snapshot.requireData);
|
||||||
|
Navigator.of(context).pop();
|
||||||
|
},
|
||||||
|
focusColor: MzanziInnovationHub.of(context)!
|
||||||
|
.theme
|
||||||
|
.successColor(),
|
||||||
|
icon: Icon(
|
||||||
|
Icons.check,
|
||||||
|
color: MzanziInnovationHub.of(context)!
|
||||||
|
.theme
|
||||||
|
.primaryColor(),
|
||||||
),
|
),
|
||||||
);
|
),
|
||||||
});
|
|
||||||
textMessage = types.TextMessage(
|
|
||||||
author: _mihAI,
|
|
||||||
createdAt: DateTime.now().millisecondsSinceEpoch,
|
|
||||||
id: const Uuid().v4(),
|
|
||||||
// metadata: <String, dynamic>{
|
|
||||||
// "thoughts": snapshot.requireData
|
|
||||||
// },
|
|
||||||
text: snapshot.requireData
|
|
||||||
.replaceAll("<think>\n\n", "Thinking:\n")
|
|
||||||
.replaceAll("<think>\n", "Thinking:\n")
|
|
||||||
.replaceAll(
|
|
||||||
"</think>\n\n", "Answer:\n"), //message.text,
|
|
||||||
);
|
|
||||||
|
|
||||||
_addMessage(textMessage);
|
// MIHButton(
|
||||||
Navigator.of(context).pop();
|
// onTap: () {
|
||||||
},
|
// _captureAIResponse(snapshot.requireData);
|
||||||
buttonText: "Continue",
|
// Navigator.of(context).pop();
|
||||||
buttonColor:
|
// },
|
||||||
MzanziInnovationHub.of(context)!.theme.successColor(),
|
// buttonText: "Continue",
|
||||||
textColor:
|
// buttonColor: MzanziInnovationHub.of(context)!
|
||||||
MzanziInnovationHub.of(context)!.theme.primaryColor(),
|
// .theme
|
||||||
),
|
// .successColor(),
|
||||||
|
// textColor: MzanziInnovationHub.of(context)!
|
||||||
|
// .theme
|
||||||
|
// .primaryColor(),
|
||||||
|
// ),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
);
|
);
|
||||||
@@ -202,15 +191,28 @@ class _AiChatState extends State<AiChat> {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
void _loadMessages() async {
|
void _captureAIResponse(String responseMessage) {
|
||||||
final response = await rootBundle.loadString('assets/messages.json');
|
types.TextMessage textMessage;
|
||||||
final messages = (jsonDecode(response) as List)
|
|
||||||
.map((e) => types.Message.fromJson(e as Map<String, dynamic>))
|
|
||||||
.toList();
|
|
||||||
|
|
||||||
setState(() {
|
setState(() {
|
||||||
_messages = messages;
|
_chatHistory.add(
|
||||||
|
ollama.Message(
|
||||||
|
role: ollama.MessageRole.assistant,
|
||||||
|
content: responseMessage,
|
||||||
|
),
|
||||||
|
);
|
||||||
});
|
});
|
||||||
|
textMessage = types.TextMessage(
|
||||||
|
author: _mihAI,
|
||||||
|
createdAt: DateTime.now().millisecondsSinceEpoch,
|
||||||
|
id: const Uuid().v4(),
|
||||||
|
|
||||||
|
text: responseMessage
|
||||||
|
.replaceAll("<think>\n\n", "**Thinking:**\n")
|
||||||
|
.replaceAll("<think>\n", "**Thinking:**\n")
|
||||||
|
.replaceAll("</think>\n\n", "\n**Answer:**\n"), //message.text,
|
||||||
|
);
|
||||||
|
|
||||||
|
_addMessage(textMessage);
|
||||||
}
|
}
|
||||||
|
|
||||||
Stream<String> _generateChatCompletionWithHistoryStream(
|
Stream<String> _generateChatCompletionWithHistoryStream(
|
||||||
@@ -234,20 +236,14 @@ class _AiChatState extends State<AiChat> {
|
|||||||
setState(() {
|
setState(() {
|
||||||
_aiThinking = false;
|
_aiThinking = false;
|
||||||
});
|
});
|
||||||
// print(text);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void _resetChat() {
|
void _resetChat() {
|
||||||
setState(() {
|
setState(() {
|
||||||
_messages = [];
|
_messages = [];
|
||||||
_chatHistory = [];
|
_chatHistory = [];
|
||||||
|
|
||||||
_loadMessages();
|
_loadMessages();
|
||||||
});
|
});
|
||||||
// Navigator.of(context).popAndPushNamed(
|
|
||||||
// '/mzansi-ai',
|
|
||||||
// arguments: widget.signedInUser,
|
|
||||||
// );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ChatTheme getChatTheme() {
|
ChatTheme getChatTheme() {
|
||||||
@@ -301,14 +297,14 @@ class _AiChatState extends State<AiChat> {
|
|||||||
firstName: "Mzansi AI",
|
firstName: "Mzansi AI",
|
||||||
id: const Uuid().v4(),
|
id: const Uuid().v4(),
|
||||||
);
|
);
|
||||||
_modelCopntroller.text = 'deepseek-r1:1.5b';
|
_modelCopntroller.text = 'deepseek-r1';
|
||||||
_fontSizeCopntroller.text = _chatFrontSize.ceil().toString();
|
_fontSizeCopntroller.text = _chatFrontSize.ceil().toString();
|
||||||
// _chatHistory.add(
|
_chatHistory.add(
|
||||||
// ollama.Message(
|
ollama.Message(
|
||||||
// role: ollama.MessageRole.system,
|
role: ollama.MessageRole.system,
|
||||||
// content: systemPromt,
|
content: systemPromt,
|
||||||
// ),
|
),
|
||||||
// );
|
);
|
||||||
_loadMessages();
|
_loadMessages();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -406,7 +402,10 @@ class _AiChatState extends State<AiChat> {
|
|||||||
child: MIHDropdownField(
|
child: MIHDropdownField(
|
||||||
controller: _modelCopntroller,
|
controller: _modelCopntroller,
|
||||||
hintText: "AI Model",
|
hintText: "AI Model",
|
||||||
dropdownOptions: const ['deepseek-r1:1.5b'],
|
dropdownOptions: const [
|
||||||
|
'deepseek-r1:1.5b',
|
||||||
|
'deepseek-r1'
|
||||||
|
],
|
||||||
required: true,
|
required: true,
|
||||||
editable: true,
|
editable: true,
|
||||||
),
|
),
|
||||||
|
|||||||
Reference in New Issue
Block a user