diff --git a/Frontend/android/app/src/main/AndroidManifest.xml b/Frontend/android/app/src/main/AndroidManifest.xml
index 74a51a4f..6bdf2e76 100644
--- a/Frontend/android/app/src/main/AndroidManifest.xml
+++ b/Frontend/android/app/src/main/AndroidManifest.xml
@@ -17,6 +17,11 @@
+
+
+
+
+
+
+
+
diff --git a/Frontend/ios/Runner/Info.plist b/Frontend/ios/Runner/Info.plist
index 53e112f3..e74bd533 100644
--- a/Frontend/ios/Runner/Info.plist
+++ b/Frontend/ios/Runner/Info.plist
@@ -2,6 +2,10 @@
+ NSMicrophoneUsageDescription
+ This app needs access to your microphone to enable voice input for the chat.
+ NSSpeechRecognitionUsageDescription
+ This app uses speech recognition to convert your voice messages into text.
SKAdNetworkItems
diff --git a/Frontend/lib/mih_components/mih_providers/mzansi_ai_provider.dart b/Frontend/lib/mih_components/mih_providers/mzansi_ai_provider.dart
index a514acfc..7f3e35e8 100644
--- a/Frontend/lib/mih_components/mih_providers/mzansi_ai_provider.dart
+++ b/Frontend/lib/mih_components/mih_providers/mzansi_ai_provider.dart
@@ -1,5 +1,6 @@
import 'package:flutter/material.dart';
import 'package:flutter_ai_toolkit/flutter_ai_toolkit.dart';
+import 'package:flutter_markdown_plus/flutter_markdown_plus.dart';
import 'package:mzansi_innovation_hub/main.dart';
import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_icons.dart';
import 'package:mzansi_innovation_hub/mih_components/mih_providers/ollama_provider.dart';
@@ -63,6 +64,75 @@ class MzansiAiProvider extends ChangeNotifier {
notifyListeners();
}
+ void clearStartUpQuestion() {
+ startUpQuestion = null;
+ }
+
+ MarkdownStyleSheet getLlmChatMarkdownStyle(BuildContext context) {
+ TextStyle body = TextStyle(
+ color: MihColors.getPrimaryColor(
+ MzansiInnovationHub.of(context)!.theme.mode == "Dark"),
+ fontSize: 16,
+ fontWeight: FontWeight.w400,
+ );
+ TextStyle heading1 = TextStyle(
+ color: MihColors.getPrimaryColor(
+ MzansiInnovationHub.of(context)!.theme.mode == "Dark"),
+ fontSize: 24,
+ fontWeight: FontWeight.w400,
+ );
+ TextStyle heading2 = TextStyle(
+ color: MihColors.getPrimaryColor(
+ MzansiInnovationHub.of(context)!.theme.mode == "Dark"),
+ fontSize: 20,
+ fontWeight: FontWeight.w400,
+ );
+ TextStyle code = TextStyle(
+ color: MihColors.getSecondaryColor(
+ MzansiInnovationHub.of(context)!.theme.mode == "Dark"),
+ fontSize: 16,
+ fontWeight: FontWeight.w400,
+ );
+ BoxDecoration codeBlock = BoxDecoration(
+ borderRadius: BorderRadius.only(
+ topLeft: Radius.circular(10),
+ topRight: Radius.circular(10),
+ bottomLeft: Radius.circular(10),
+ bottomRight: Radius.circular(10),
+ ),
+ color: MihColors.getHighlightColor(
+ MzansiInnovationHub.of(context)!.theme.mode != "Dark"),
+ boxShadow: [
+ BoxShadow(
+ color: Colors.black.withAlpha(76),
+ blurRadius: 8,
+ offset: Offset(2, 2),
+ ),
+ ],
+ );
+ return MarkdownStyleSheet(
+ a: body,
+ blockquote: body,
+ checkbox: body,
+ del: body,
+ em: body.copyWith(fontStyle: FontStyle.italic),
+ h1: heading1,
+ h2: heading2,
+ h3: body.copyWith(fontWeight: FontWeight.bold),
+ h4: body,
+ h5: body,
+ h6: body,
+ listBullet: body,
+ img: body,
+ strong: body.copyWith(fontWeight: FontWeight.bold),
+ p: body,
+ tableBody: body,
+ tableHead: body,
+ code: code,
+ codeblockDecoration: codeBlock,
+ );
+ }
+
LlmChatViewStyle? getChatStyle(BuildContext context) {
return LlmChatViewStyle(
backgroundColor: MihColors.getPrimaryColor(
@@ -153,6 +223,7 @@ class MzansiAiProvider extends ChangeNotifier {
),
],
),
+ markdownStyle: getLlmChatMarkdownStyle(context),
),
// User Chat Style
userMessageStyle: UserMessageStyle(
@@ -231,17 +302,18 @@ class MzansiAiProvider extends ChangeNotifier {
MzansiInnovationHub.of(context)!.theme.mode == "Dark"),
),
cancelButtonStyle: ActionButtonStyle(
- iconDecoration: BoxDecoration(
- color: MihColors.getRedColor(
- MzansiInnovationHub.of(context)!.theme.mode == "Dark"),
- borderRadius: BorderRadius.circular(25),
- ),
- iconColor: MihColors.getSecondaryInvertedColor(
+ iconDecoration: BoxDecoration(
+ color: MihColors.getRedColor(
MzansiInnovationHub.of(context)!.theme.mode == "Dark"),
- textStyle: TextStyle(
- color: MihColors.getPrimaryColor(
- MzansiInnovationHub.of(context)!.theme.mode == "Dark"),
- )),
+ borderRadius: BorderRadius.circular(25),
+ ),
+ iconColor: MihColors.getSecondaryInvertedColor(
+ MzansiInnovationHub.of(context)!.theme.mode == "Dark"),
+ textStyle: TextStyle(
+ color: MihColors.getPrimaryColor(
+ MzansiInnovationHub.of(context)!.theme.mode == "Dark"),
+ ),
+ ),
);
}
}
diff --git a/Frontend/lib/mih_components/mih_providers/ollama_provider.dart b/Frontend/lib/mih_components/mih_providers/ollama_provider.dart
index 5b4ee268..e344279d 100644
--- a/Frontend/lib/mih_components/mih_providers/ollama_provider.dart
+++ b/Frontend/lib/mih_components/mih_providers/ollama_provider.dart
@@ -2,6 +2,7 @@ import 'dart:convert';
import 'package:flutter/foundation.dart';
import 'package:flutter_ai_toolkit/flutter_ai_toolkit.dart';
+import 'package:ken_logger/ken_logger.dart';
import 'package:ollama_dart/ollama_dart.dart';
class OllamaProvider extends LlmProvider with ChangeNotifier {
@@ -40,16 +41,19 @@ class OllamaProvider extends LlmProvider with ChangeNotifier {
String prompt, {
Iterable attachments = const [],
}) async* {
+ KenLogger.success("sendMessageStream called with: $prompt");
final userMessage = ChatMessage.user(prompt, attachments);
final llmMessage = ChatMessage.llm();
_history.addAll([userMessage, llmMessage]);
notifyListeners();
+ KenLogger.success("History after adding messages: ${_history.length}");
final messages = _mapToOllamaMessages(_history);
final stream = _generateStream(messages);
yield* stream.map((chunk) {
llmMessage.append(chunk);
return chunk;
});
+ KenLogger.success("Stream completed for: $prompt");
notifyListeners();
}
diff --git a/Frontend/lib/mih_packages/mih_home/package_tools/mih_personal_home.dart b/Frontend/lib/mih_packages/mih_home/package_tools/mih_personal_home.dart
index 6daf28fb..1c3789ed 100644
--- a/Frontend/lib/mih_packages/mih_home/package_tools/mih_personal_home.dart
+++ b/Frontend/lib/mih_packages/mih_home/package_tools/mih_personal_home.dart
@@ -286,11 +286,11 @@ class _MihPersonalHomeState extends State
hintColor: MihColors.getPrimaryColor(
MzansiInnovationHub.of(context)!.theme.mode == "Dark"),
onPrefixIconTap: () {
- mzansiAiProvider
- .setStartUpQuestion(searchController.text);
- context.goNamed(
- "mzansiAi",
- );
+ if (searchController.text.isNotEmpty) {
+ mzansiAiProvider
+ .setStartUpQuestion(searchController.text);
+ }
+ context.goNamed("mzansiAi");
searchController.clear();
},
searchFocusNode: _searchFocusNode,
diff --git a/Frontend/lib/mih_packages/mzansi_ai/mzansi_ai.dart b/Frontend/lib/mih_packages/mzansi_ai/mzansi_ai.dart
index 87813973..cea2fd78 100644
--- a/Frontend/lib/mih_packages/mzansi_ai/mzansi_ai.dart
+++ b/Frontend/lib/mih_packages/mzansi_ai/mzansi_ai.dart
@@ -3,7 +3,6 @@ import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_
import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_package_action.dart';
import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_package_tools.dart';
import 'package:mzansi_innovation_hub/mih_components/mih_providers/mzansi_ai_provider.dart';
-import 'package:mzansi_innovation_hub/mih_packages/mzansi_ai/package_tools/ai_chat.dart';
import 'package:flutter/material.dart';
import 'package:mzansi_innovation_hub/mih_packages/mzansi_ai/package_tools/mih_ai_chat.dart';
import 'package:provider/provider.dart';
@@ -37,9 +36,9 @@ class _MzansiAiState extends State {
temp[const Icon(Icons.chat)] = () {
context.read().setToolIndex(0);
};
- temp[const Icon(Icons.chat)] = () {
- context.read().setToolIndex(1);
- };
+ // temp[const Icon(Icons.chat)] = () {
+ // context.read().setToolIndex(1);
+ // };
return MihPackageTools(
tools: temp,
@@ -49,7 +48,7 @@ class _MzansiAiState extends State {
List getToolBody() {
List toolBodies = [
- AiChat(),
+ // AiChat(),
MihAiChat(),
];
return toolBodies;
@@ -58,7 +57,7 @@ class _MzansiAiState extends State {
List getToolTitle() {
List toolTitles = [
"Ask Mzansi",
- "New Chat",
+ // "New Chat",
];
return toolTitles;
}
diff --git a/Frontend/lib/mih_packages/mzansi_ai/package_tools/ai_chat.dart b/Frontend/lib/mih_packages/mzansi_ai/package_tools/ai_chat.dart
index 61c9dbc9..3d6df16e 100644
--- a/Frontend/lib/mih_packages/mzansi_ai/package_tools/ai_chat.dart
+++ b/Frontend/lib/mih_packages/mzansi_ai/package_tools/ai_chat.dart
@@ -1,7 +1,6 @@
import 'dart:async';
import 'dart:convert';
import 'package:flutter_speed_dial/flutter_speed_dial.dart';
-import 'package:gpt_markdown/gpt_markdown.dart';
import 'package:mzansi_innovation_hub/main.dart';
import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_icons.dart';
import 'package:mzansi_innovation_hub/mih_components/mih_providers/mzansi_ai_provider.dart';
@@ -221,8 +220,21 @@ class _AiChatState extends State {
child: Column(
mainAxisSize: MainAxisSize.max,
children: [
+ // SelectionArea(
+ // child: GptMarkdown(
+ // snapshot.requireData,
+ // textAlign: TextAlign.left,
+ // style: TextStyle(
+ // color: MihColors.getSecondaryColor(
+ // MzansiInnovationHub.of(context)!.theme.mode ==
+ // "Dark"),
+ // fontSize: _chatFrontSize,
+ // fontWeight: FontWeight.bold,
+ // ),
+ // ),
+ // ),
SelectionArea(
- child: GptMarkdown(
+ child: Text(
snapshot.requireData,
textAlign: TextAlign.left,
style: TextStyle(
diff --git a/Frontend/lib/mih_packages/mzansi_ai/package_tools/mih_ai_chat.dart b/Frontend/lib/mih_packages/mzansi_ai/package_tools/mih_ai_chat.dart
index 5865ff8e..849edef8 100644
--- a/Frontend/lib/mih_packages/mzansi_ai/package_tools/mih_ai_chat.dart
+++ b/Frontend/lib/mih_packages/mzansi_ai/package_tools/mih_ai_chat.dart
@@ -124,54 +124,68 @@ class _MihAiChatState extends State {
}
Future initTts() async {
- List