Add function message role and function name
This commit is contained in:
3
.gitignore
vendored
3
.gitignore
vendored
@ -9,4 +9,5 @@ example/.env
|
||||
env.g.dart
|
||||
.env
|
||||
*.mp3
|
||||
*.png
|
||||
*.png
|
||||
.idea/
|
||||
|
@ -1,3 +1,5 @@
|
||||
import 'dart:convert';
|
||||
|
||||
import 'package:dart_openai/dart_openai.dart';
|
||||
|
||||
import 'env/env.dart';
|
||||
@ -5,39 +7,100 @@ import 'env/env.dart';
|
||||
Future<void> main() async {
|
||||
OpenAI.apiKey = Env.apiKey;
|
||||
|
||||
final chatRes = await OpenAI.instance.chat.create(
|
||||
model: "gpt-3.5-turbo-0613",
|
||||
messages: [
|
||||
OpenAIChatCompletionChoiceMessageModel(
|
||||
content:
|
||||
"send an email with a message asking about weather in Marrakech",
|
||||
role: OpenAIChatMessageRole.user,
|
||||
),
|
||||
],
|
||||
functions: [
|
||||
OpenAIFunctionModel(
|
||||
name: "sendEmail",
|
||||
description: "sends an email with the given message",
|
||||
parameters: OpenAIFunctionParameters.fromProperties(
|
||||
[
|
||||
OpenAIFunctionProperty(
|
||||
name: "message",
|
||||
type: 'string',
|
||||
),
|
||||
],
|
||||
final function = OpenAIFunctionModel(
|
||||
name: "getCurrentWeather",
|
||||
description: "Get the current weather in a given location",
|
||||
parameters: OpenAIFunctionParameters.fromProperties(
|
||||
[
|
||||
OpenAIFunctionProperty(
|
||||
name: "location",
|
||||
description: 'The city and state, e.g. San Francisco, CA',
|
||||
type: OpenAIFunctionProperty.functionTypeString,
|
||||
isRequired: true,
|
||||
),
|
||||
),
|
||||
],
|
||||
OpenAIFunctionProperty(
|
||||
name: "unit",
|
||||
description: 'The unit of temperature to return',
|
||||
type: OpenAIFunctionProperty.functionTypeString,
|
||||
enumValues: ["celsius", "fahrenheit"],
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
|
||||
final funcCall = chatRes.choices.first.message.functionCall;
|
||||
final userMsg = OpenAIChatCompletionChoiceMessageModel(
|
||||
content: "What’s the weather like in Boston right now?",
|
||||
role: OpenAIChatMessageRole.user,
|
||||
);
|
||||
|
||||
if (funcCall != null && funcCall.name == "sendEmail") {
|
||||
final message = funcCall.arguments["message"];
|
||||
sendEmail(message);
|
||||
final chatRes1 = await OpenAI.instance.chat.create(
|
||||
model: "gpt-3.5-turbo-0613",
|
||||
messages: [userMsg],
|
||||
functions: [function],
|
||||
);
|
||||
|
||||
final assistantMsg1 = chatRes1.choices.first.message;
|
||||
final funcCall = assistantMsg1.functionCall;
|
||||
|
||||
if (funcCall == null || funcCall.name != "getCurrentWeather") {
|
||||
print(assistantMsg1.content);
|
||||
return;
|
||||
}
|
||||
|
||||
final weather = getCurrentWeather(
|
||||
location: funcCall.arguments["location"],
|
||||
unit: funcCall.arguments["unit"],
|
||||
);
|
||||
|
||||
final functionMsg = OpenAIChatCompletionChoiceMessageModel(
|
||||
functionName: function.name,
|
||||
content: json.encode(weather.toMap()),
|
||||
role: OpenAIChatMessageRole.function,
|
||||
);
|
||||
|
||||
final chatRes2 = await OpenAI.instance.chat.create(
|
||||
model: "gpt-3.5-turbo-0613",
|
||||
messages: [
|
||||
userMsg,
|
||||
assistantMsg1,
|
||||
functionMsg,
|
||||
],
|
||||
functions: [function],
|
||||
);
|
||||
|
||||
final assistantMsg2 = chatRes2.choices.first.message;
|
||||
|
||||
print(assistantMsg2.content);
|
||||
// The weather in Boston right now is sunny with a temperature of 22 degrees Celsius.
|
||||
}
|
||||
|
||||
Weather getCurrentWeather({
|
||||
required String location,
|
||||
String? unit = "celsius",
|
||||
}) {
|
||||
return Weather(
|
||||
temperature: 22,
|
||||
unit: unit ?? "celsius",
|
||||
description: "Sunny",
|
||||
);
|
||||
}
|
||||
|
||||
class Weather {
|
||||
final int temperature;
|
||||
final String unit;
|
||||
final String description;
|
||||
|
||||
const Weather({
|
||||
required this.temperature,
|
||||
required this.unit,
|
||||
required this.description,
|
||||
});
|
||||
|
||||
Map<String, dynamic> toMap() {
|
||||
return {
|
||||
'temperature': temperature,
|
||||
'unit': unit,
|
||||
'description': description,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
void sendEmail(String message) {
|
||||
print("message: $message... is sent successfully.");
|
||||
}
|
||||
|
@ -11,11 +11,20 @@ final class OpenAIChatCompletionChoiceMessageModel {
|
||||
/// The [content] of the message.
|
||||
final String content;
|
||||
|
||||
/// The function that the model is requesting to call.
|
||||
final FunctionCallResponse? functionCall;
|
||||
|
||||
/// The name of the function that was called.
|
||||
final String? functionName;
|
||||
|
||||
bool get hasFunctionCall => functionCall != null;
|
||||
|
||||
@override
|
||||
int get hashCode {
|
||||
return role.hashCode ^ content.hashCode;
|
||||
return role.hashCode ^
|
||||
content.hashCode ^
|
||||
functionCall.hashCode ^
|
||||
functionName.hashCode;
|
||||
}
|
||||
|
||||
/// {@macro openai_chat_completion_choice_message_model}
|
||||
@ -23,10 +32,9 @@ final class OpenAIChatCompletionChoiceMessageModel {
|
||||
required this.role,
|
||||
required this.content,
|
||||
this.functionCall,
|
||||
this.functionName,
|
||||
});
|
||||
|
||||
bool get hasFunctionCall => functionCall != null;
|
||||
|
||||
/// This is used to convert a [Map<String, dynamic>] object to a [OpenAIChatCompletionChoiceMessageModel] object.
|
||||
factory OpenAIChatCompletionChoiceMessageModel.fromMap(
|
||||
Map<String, dynamic> json,
|
||||
@ -47,15 +55,24 @@ final class OpenAIChatCompletionChoiceMessageModel {
|
||||
"role": role.name,
|
||||
"content": content,
|
||||
if (functionCall != null) "function_call": functionCall!.toMap(),
|
||||
if (functionName != null) "name": functionName,
|
||||
};
|
||||
}
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
String str = 'OpenAIChatCompletionChoiceMessageModel('
|
||||
'role: $role, '
|
||||
'content: $content, ';
|
||||
if (functionCall != null) {
|
||||
return 'OpenAIChatCompletionChoiceMessageModel(role: $role, content: $content, functionCall: $functionCall)';
|
||||
str += 'functionCall: $functionCall, ';
|
||||
}
|
||||
return 'OpenAIChatCompletionChoiceMessageModel(role: $role, content: $content)';
|
||||
if (functionName != null) {
|
||||
str += 'functionName: $functionName, ';
|
||||
}
|
||||
str += ')';
|
||||
|
||||
return str;
|
||||
}
|
||||
|
||||
@override
|
||||
@ -65,6 +82,7 @@ final class OpenAIChatCompletionChoiceMessageModel {
|
||||
return other is OpenAIChatCompletionChoiceMessageModel &&
|
||||
other.role == role &&
|
||||
other.content == content &&
|
||||
other.functionCall == functionCall;
|
||||
other.functionCall == functionCall &&
|
||||
other.functionName == functionName;
|
||||
}
|
||||
}
|
||||
|
@ -140,7 +140,7 @@ class FunctionCallResponse {
|
||||
Map<String, dynamic> toMap() {
|
||||
return {
|
||||
'name': name,
|
||||
'arguments': arguments,
|
||||
'arguments': json.encode(arguments),
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -4,4 +4,4 @@ enum OpenAIImageResponseFormat { url, b64Json }
|
||||
|
||||
enum OpenAIAudioResponseFormat { json, text, srt, verbose_json, vtt }
|
||||
|
||||
enum OpenAIChatMessageRole { system, user, assistant }
|
||||
enum OpenAIChatMessageRole { system, user, assistant, function }
|
||||
|
Reference in New Issue
Block a user