Skip to content

Commit

Permalink
Merge pull request #8 from glowbom/korbit-feedback
Browse files Browse the repository at this point in the history
Korbit feedback - code design
  • Loading branch information
jacob-i authored Dec 11, 2023
2 parents c3cdad0 + 1ec3c82 commit a4be077
Show file tree
Hide file tree
Showing 8 changed files with 115 additions and 82 deletions.
10 changes: 9 additions & 1 deletion app/lib/ai_settings_dialog.dart
Original file line number Diff line number Diff line change
Expand Up @@ -95,14 +95,22 @@ class _AiSettingsDialogState extends State<AiSettingsDialog> {
GlobalSettings().systemHuggingFacePrompt;
}

void _saveSettings(BuildContext context) {
void _saveOpenAISettings() {
OpenAI_API.setModel(GlobalSettings().selectedModel);
OpenAI_API.setSystemPrompt(GlobalSettings().systemPrompt);
OpenAI_API.setSelectedLanguage(GlobalSettings().selectedLanguage);
}

void _saveHuggingFaceSettings() {
HuggingFace_API.setModel(_modelIdController.text);
HuggingFace_API.setTemplate(_templateController.text);
HuggingFace_API.setSendMessages(_sendMessageHistory);
HuggingFace_API.setSystemMessage(GlobalSettings().systemHuggingFacePrompt);
}

void _saveSettings(BuildContext context) {
_saveOpenAISettings();
_saveHuggingFaceSettings();

// Save the system prompt to use with API calls
Navigator.pop(context); // Hide the dialog
Expand Down
97 changes: 61 additions & 36 deletions app/lib/chat_screen.dart
Original file line number Diff line number Diff line change
Expand Up @@ -63,30 +63,52 @@ class _ChatScreenState extends State<ChatScreen> {
@override
void initState() {
super.initState();
initializeVoiceEnabled();
loadGlobalSettings();
loadAPIKey();
}

void initializeVoiceEnabled() {
_voiceEnabled = widget._voice;
GlobalSettings().loadDialogValues(widget._selectedModel,
widget._selectedLanguage, widget._systemPrompt, widget._autonomousMode);
}

OpenAI_API.loadOat().then((_) {
setState(() {});
});
void loadGlobalSettings() {
GlobalSettings().loadDialogValues(
widget._selectedModel,
widget._selectedLanguage,
widget._systemPrompt,
widget._autonomousMode,
);
}

// Refresh the chat screen and handle text-to-speech functionality
void refresh() {
void loadAPIKey() {
OpenAI_API.loadOat().then((_) => setState(() {}));
}

// Refresh the UI state of the chat screen
void refreshUI() {
setState(() {});
}

// Handle text-to-speech functionality independently
void handleTextToSpeech() {
if (widget._voice && _voiceEnabled) {
try {
if (_messages.isNotEmpty &&
_messages[0].userId == '007' &&
_planImplementationInProgress == false) {
!_planImplementationInProgress) {
textToSpeech.speakText(_messages[0].text,
language: GlobalSettings().selectedLanguage);
}
} catch (e) {
print('Error: $e'); // Log the exception
print('Error in text-to-speech: $e');
}
}
setState(() {});
}

void refresh() {
handleTextToSpeech();
refreshUI();
}

void _showApiKeyDialog() {
Expand Down Expand Up @@ -368,44 +390,47 @@ class _ChatScreenState extends State<ChatScreen> {
title: Text('Share Glowby'),
content: SingleChildScrollView(
child: ListBody(
children: <Widget>[
_buildLinkItem(
'Glowby GPT', 'https://glowbom.com/glowby/gpt', context),
Padding(padding: EdgeInsets.all(10.0)),
_buildLinkItem('GitHub Repository',
'https://github.com/glowbom/glowby', context),
Padding(padding: EdgeInsets.all(10.0)),
_buildLinkItem(
'Feature List',
'https://twitter.com/jacobilin/status/1649443429347397632',
context),
Padding(padding: EdgeInsets.all(10.0)),
_buildLinkItem(
'Website (glowbom.com)', 'https://glowbom.com/', context),
Padding(padding: EdgeInsets.all(10.0)),
_buildLinkItem('Twitter: @GlowbomCorp',
'https://twitter.com/GlowbomCorp', context),
Padding(padding: EdgeInsets.all(10.0)),
_buildLinkItem(
'YouTube Channel',
'https://www.youtube.com/channel/UCrYQEQPhAHmn7N8W58nNwOw',
context),
],
children: _buildLinkItems(context),
),
),
actions: <Widget>[
TextButton(
child: Text('Close'),
onPressed: () {
Navigator.of(context).pop();
},
onPressed: () => Navigator.of(context).pop(),
),
],
);
},
);
}

List<Widget> _buildLinkItems(BuildContext context) {
final links = [
{'title': 'Glowby GPT', 'url': 'https://glowbom.com/glowby/gpt'},
{
'title': 'GitHub Repository',
'url': 'https://github.com/glowbom/glowby'
},
{
'title': 'Feature List',
'url': 'https://twitter.com/jacobilin/status/1649443429347397632'
},
{'title': 'Website (glowbom.com)', 'url': 'https://glowbom.com/'},
{
'title': 'Twitter: @GlowbomCorp',
'url': 'https://twitter.com/GlowbomCorp'
},
{
'title': 'YouTube Channel',
'url': 'https://www.youtube.com/channel/UCrYQEQPhAHmn7N8W58nNwOw'
}
];

return links
.map((link) => _buildLinkItem(link['title']!, link['url']!, context))
.toList();
}

Widget _buildLinkItem(String text, String url, BuildContext context) {
return Row(
children: [
Expand Down
54 changes: 21 additions & 33 deletions app/lib/hugging_face_api.dart
Original file line number Diff line number Diff line change
Expand Up @@ -132,51 +132,39 @@ class HuggingFace_API {
// generate('google/flan-t5-large', 'What\'s the best way to play a guitar?', '[{"generated_text": "***"}]');
static Future<String?> _generate(
String modelId, String text, String template) async {
if (oat() == '') {
return 'Please enter your Hugging Face Access Token in the settings.';
if (!_isValidTokenAndModel(modelId)) {
return 'Invalid token or model ID';
}

if (modelId == '') {
return 'Please enter Model ID in the settings.';
}
final response = await _makeRequest(modelId, text);
return _processResponse(response, template);
}

static bool _isValidTokenAndModel(String modelId) {
return oat() != '' && modelId != '';
}

final token = oat();
static Future<http.Response> _makeRequest(String modelId, String text) async {
final queryUrl = 'https://api-inference.huggingface.co/models/$modelId';
final headers = {
'Content-Type': 'application/json',
'Authorization': 'Bearer $token',
'Authorization': 'Bearer ${oat()}',
};

final body = jsonEncode({
'inputs': _systemMessage == ''
'inputs': _systemMessage.isEmpty
? text
: text + ' [System message]: ' + _systemMessage,
: '$text [System message]: $_systemMessage',
});

if (kDebugMode) {
print('Request URL: $queryUrl');
}

final response =
await http.post(Uri.parse(queryUrl), headers: headers, body: body);

if (kDebugMode) {
print('Response Status Code: ${response.statusCode}');
print('Response Body: ${response.body}');
}

if (response.statusCode == 200) {
final jsonResponse = jsonDecode(response.body);
final templateJson = jsonDecode(template);
final generatedText = _findValueByTemplate(jsonResponse, templateJson);

if (kDebugMode) {
print('Generated Text: $generatedText');
}
return await http.post(Uri.parse(queryUrl), headers: headers, body: body);
}

return generatedText;
} else {
return 'Sorry, there was an error processing your request. Please try again later.';
static String? _processResponse(http.Response response, String template) {
if (response.statusCode != 200) {
return 'Error processing request';
}
final jsonResponse = jsonDecode(response.body);
final templateJson = jsonDecode(template);
return _findValueByTemplate(jsonResponse, templateJson);
}
}
2 changes: 1 addition & 1 deletion app/lib/message_bubble.dart
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ class MessageBubble extends StatelessWidget {
if (await canLaunchUrl(uri)) {
await launchUrl(uri);
} else {
throw 'Could not launch $link';
throw Exception('Could not launch $link');
}
}

Expand Down
15 changes: 13 additions & 2 deletions app/lib/new_message.dart
Original file line number Diff line number Diff line change
Expand Up @@ -270,14 +270,25 @@ class _NewMessageState extends State<NewMessage> {
}

void _stopProcessing() {
// Set the stop requested flag
_stopRequested = true;

// Use setState to update the state and UI accordingly
setState(() {
// Set the processing flag to false
_isProcessing = false;
// Remove the typing message
widget._messages.removeAt(0);

// If there's a typing message, remove it
if (widget._messages.isNotEmpty &&
widget._messages[0].text == "typing...") {
widget._messages.removeAt(0);
}

// Refresh the widget to reflect the changes
widget._refresh();
});

// Cancel any ongoing network operation if it exists
ai.getCurrentNetworkOperation()?.cancel();
}

Expand Down
9 changes: 4 additions & 5 deletions app/lib/openai_api.dart
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,13 @@ import 'package:async/async.dart';
import 'package:glowby/hugging_face_api.dart';
import 'package:glowby/pulze_ai_api.dart';

int totalTokensUsed = 0;

class OpenAI_API {
static final OpenAI_API _instance = OpenAI_API._privateConstructor();
factory OpenAI_API() => _instance;
OpenAI_API._privateConstructor();

String _apiKey = '';
static int _totalTokensUsed = 0;

static String oat() => OpenAI_API()._oat();
static void setOat(String value) => OpenAI_API()._setOat(value);
Expand Down Expand Up @@ -387,18 +386,18 @@ class OpenAI_API {

// Add the tokens used in this response to the total tokens used
int tokensUsed = responseBody['usage']['total_tokens'];
totalTokensUsed += tokensUsed;
_totalTokensUsed += tokensUsed;

// Calculate the cost of the tokens used
double cost = tokensUsed * 0.002 / 1000;
if (kDebugMode) {
// Print the tokens used and the cost to the console
print('Tokens used in this response: $tokensUsed');
print('Cost of this response: \$${cost.toStringAsFixed(5)}');
print('Total tokens used so far: $totalTokensUsed');
print('Total tokens used so far: $_totalTokensUsed');
}

double totalCost = totalTokensUsed * 0.002 / 1000;
double totalCost = _totalTokensUsed * 0.002 / 1000;
if (kDebugMode) {
print('Total cost so far: \$${totalCost.toStringAsFixed(5)}');
}
Expand Down
4 changes: 3 additions & 1 deletion app/lib/text_to_speech.dart
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ import 'dart:async';
import 'package:flutter_tts/flutter_tts.dart';

class TextToSpeech {
static const String TYPING_INDICATOR = 'typing...';

FlutterTts _flutterTts = FlutterTts();

static final Map<String, String> _languageCodes = {
Expand Down Expand Up @@ -61,7 +63,7 @@ class TextToSpeech {
static String? lastLanguage = null;

Future<void> speakText(String text, {String language = 'en-US'}) async {
if (text == 'typing...') {
if (text == TYPING_INDICATOR) {
return;
}

Expand Down
6 changes: 3 additions & 3 deletions app/lib/utils.dart
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ class Utils {
if (await canLaunchUrlString(url)) {
await launchUrlString(url);
} else {
throw 'Could not launch $url';
throw Exception('Could not launch $url');
}
}

Expand Down Expand Up @@ -55,10 +55,10 @@ class Utils {
final base64Image = base64Encode(imageData);
return base64Image;
} else {
throw 'Failed to download image: ${response.statusCode}';
throw Exception('Failed to download image: ${response.statusCode}');
}
} catch (e) {
throw 'Failed to save image: ${e.toString()}';
throw Exception('Failed to save image: ${e.toString()}');
}
}

Expand Down

0 comments on commit a4be077

Please sign in to comment.