v1.0.13 openai chat completion

This commit is contained in:
Tibor Bossanyi 2023-03-12 21:48:03 +01:00
parent f34a57e931
commit bed94e572e
7 changed files with 153 additions and 32 deletions

View File

@ -1,5 +1,8 @@
Workout Test and Diet 4 You Common Util Functions
Version 1.0.13
OpenAI chat completion extension
Version 1.0.12
CustomerProperty and CustomerMembership fromJson

View File

@ -119,6 +119,8 @@ class Cache with Logging {
static String baseUrlLive = 'https://api.workouttest.org/api/';
static String baseUrlTest = 'https://apitest.workouttest.org/api/';
static String baseUrlDiet = 'https://api.diet4you.eu/api/';
static String baseUrlDietTest = 'https://apitest.diet4you.eu/api/';
static String baseUrlLocal = 'http://localhost:8443/api/';
late String baseUrl;
static const String mediaUrl = 'https://admin.workouttest.org/media/';
@ -214,6 +216,14 @@ class Cache with Logging {
baseUrl = baseUrlTest;
}
void setDietTestBaseUrl() {
baseUrl = baseUrlDietTest;
}
void setDietBaseUrl() {
baseUrl = baseUrlDiet;
}
void setLocalBaseUrl() {
baseUrl = baseUrlLocal;
}
@ -563,8 +573,7 @@ class Cache with Logging {
ExercisePlan? getMyExercisePlan() => _myExercisePlan;
void setMyExercisePlanDetails(LinkedHashMap<int, ExercisePlanDetail> listExercisePlanDetail) =>
_myExercisesPlanDetails = listExercisePlanDetail;
void setMyExercisePlanDetails(LinkedHashMap<int, ExercisePlanDetail> listExercisePlanDetail) => _myExercisesPlanDetails = listExercisePlanDetail;
void addToMyExercisePlanDetails(ExercisePlanDetail detail) => _myExercisesPlanDetails[detail.exerciseTypeId] = detail;
@ -578,8 +587,7 @@ class Cache with Logging {
void deleteMyExercisePlanDetail(ExercisePlanDetail detail) => deleteMyExercisePlanDetailByExerciseTypeId(detail.exerciseTypeId);
void deletedMyExercisePlanDetail(ExercisePlanDetail detail) =>
_myExercisesPlanDetails[detail.exerciseTypeId]!.change = ModelChange.deleted;
void deletedMyExercisePlanDetail(ExercisePlanDetail detail) => _myExercisesPlanDetails[detail.exerciseTypeId]!.change = ModelChange.deleted;
void deleteMyExercisePlanDetailByExerciseTypeId(int exerciseTypeId) {
_myExercisesPlanDetails[exerciseTypeId]!.change = ModelChange.delete;

View File

@ -0,0 +1,25 @@
class OpenAIChat {
int id = 0;
late String messages; // JSON of ChatMessage
String modelName = "gpt-3.5-turbo";
double temperature = 0.1;
OpenAIChat(this.messages, {String? modelName, double? temperature});
OpenAIChat.fromJson(Map json) {
id = json["id"];
messages = json['messages'];
modelName = json['modelName'];
temperature = json['temperature'];
}
Map<String, dynamic> toJson() => {
"id": id,
"messages": messages,
"modelName": modelName,
"temperature": temperature,
};
@override
String toString() => toJson().toString();
}

View File

@ -0,0 +1,41 @@
enum ChatRole { user, assistant, system }
extension ChatRoleExt on ChatRole {
String enumToStr() => toString().split(".").last;
bool equalsTo(ChatRole role) => toString() == role.toString();
bool equalsStringTo(String role) => enumToStr() == role;
}
class OpenAIChatMessage {
late ChatRole role; // JSON of ChatMessage
late String content;
String? name;
OpenAIChatMessage(this.role, this.content, {String? name});
OpenAIChatMessage.fromJson(Map json) {
role = toChatRole(json['role']);
content = json['content'];
name = json['name'] ?? "";
}
ChatRole toChatRole(String strRole) {
ChatRole role = ChatRole.user;
for (ChatRole chatRole in ChatRole.values) {
if (chatRole.equalsStringTo(strRole)) {
role = chatRole;
break;
}
}
return role;
}
Map<String, dynamic> toJson() => {
"role": role.enumToStr(),
"content": content,
"name": name,
};
@override
String toString() => toJson().toString();
}

View File

@ -2,10 +2,10 @@ import 'dart:async';
import 'dart:convert';
import 'package:workouttest_util/model/openai.dart';
import 'package:workouttest_util/model/openai_chat.dart';
import 'package:workouttest_util/service/api.dart';
import 'package:workouttest_util/util/logging.dart';
class OpenAIApi with Logging {
final APIClient _client = APIClient();
@ -34,4 +34,17 @@ class OpenAIApi with Logging {
}
return response ?? "";
}
Future<String> getOpenAIChatCompletion(OpenAIChat openai) async {
String? response;
try {
String body = const JsonEncoder().convert(openai.toJson());
response = await _client.post("openai/chat_completion", body);
} on TimeoutException catch (_) {
log("Timeout from OpenAI");
} on Exception catch (e) {
log(e.toString());
}
return response ?? "";
}
}

View File

@ -1,6 +1,6 @@
name: workouttest_util
description: Workout Test app and web functions.
version: 1.0.12
version: 1.0.13
environment:
sdk: ">=2.18.6 <3.0.0"

View File

@ -1,8 +1,10 @@
import 'package:flutter_test/flutter_test.dart';
import 'package:workouttest_util/model/cache.dart';
import 'package:workouttest_util/model/openai.dart';
import 'package:workouttest_util/model/openai_chat.dart';
import 'package:workouttest_util/model/openai_chat_message.dart';
import 'package:workouttest_util/service/openai_service.dart';
import 'dart:convert';
void main() {
setUp(() {
@ -18,10 +20,39 @@ void main() {
test('openai with model response succesful', () async {
var api = OpenAIApi();
String question = "Készíts egy heti egészséges és változatos étrendet egy új felhasználónak az alábbi adatok alapján: férfi, 51 éves. Célja: Le szeretnék fogyni, heti mozgás: Hetente 3-4 alkalom, BMI: 24.784257517393772, BMR: 1723.75. A neve Tibi. Az egyes étkezések különbözőek legyenek, és add meg hozzájuk a mennyiséget és a kalóriatartalmat is. Vedd figyelembe, hogy a napi összes kalóriaérték 200-400 kCal-val kevesebb legyen, mint 1723.75 kCal";
String question =
"Készíts egy heti egészséges és változatos étrendet egy új felhasználónak az alábbi adatok alapján: férfi, 51 éves. Célja: Le szeretnék fogyni, heti mozgás: Hetente 3-4 alkalom, BMI: 24.784257517393772, BMR: 1723.75. A neve Tibi. Az egyes étkezések különbözőek legyenek, és add meg hozzájuk a mennyiséget és a kalóriatartalmat is. Vedd figyelembe, hogy a napi összes kalóriaérték 200-400 kCal-val kevesebb legyen, mint 1723.75 kCal";
var openai = OpenAI(question, "text-davinci-003", 0.5);
String response = await api.getOpenAICompletionWithModel(openai);
print(response);
expect(response, matches(RegExp(r'Tibi')));
});
test('openai chat completion response succesful', () async {
var api = OpenAIApi();
String content =
"Te a Diet4You applikáció asszisztense vagy. Add meg ennek az ételnek a kalória és tápanyagadatait: 'Hortobágyi palacsinta'. A válasz ez az objektum JSON alakított formája legyen: Meal [mealName: string, cal: double, ch: double, fat: double, protein: double, sugar: double, portion: double, unit: string]. A portion paraméter azt tartalmazza, hogy ebből az ételből hány gramm v. ml az átlagos adag. A unit paraméter a 'portion' mennyiségi egyésge";
OpenAIChatMessage message = OpenAIChatMessage(ChatRole.user, content);
String json = jsonEncode([message]);
var openai = OpenAIChat(json);
String response = await api.getOpenAIChatCompletion(openai);
print(response);
expect(response, matches(RegExp(r'mealName')));
});
test('openai chat completion response succesful 2', () async {
var api = OpenAIApi();
String content =
"Te a Diet4You applikáció asszisztense vagy. Add meg ennek az ételnek a kalória és tápanyagadatait: 'Szegedi halászlé'. A válasz ez az objektum JSON alakított formája legyen: Meal [mealName: string, cal: double, ch: double, fat: double, protein: double, sugar: double, portion: double, unit: string]. A portion paraméter azt tartalmazza, hogy ebből az ételből hány gramm v. ml az átlagos adag. A unit paraméter a 'portion' mennyiségi egyésge";
OpenAIChatMessage message = OpenAIChatMessage(ChatRole.user, content);
String json = jsonEncode([message]);
var openai = OpenAIChat(json);
String response = await api.getOpenAIChatCompletion(openai);
print(response);
expect(response, matches(RegExp(r'mealName')));
});
}