12using json = nlohmann::json;
17 azure_api_version = config.
check(
"api_version",
yarp::os::Value(
"2023-07-01-preview")).asString();
18 azure_deployment_id = std::getenv(
"DEPLOYMENT_ID");
19 azure_resource = std::getenv(
"AZURE_RESOURCE");
23 yWarning() <<
"Could not read env variable AZURE_RESOURCE. Device set in offline mode";
28 if (!oai.auth.SetAzureKeyEnv(
"AZURE_API_KEY"))
30 yWarning() <<
"Invalid or no azure key provided. Device set in offline mode.";
35 bool has_prompt_file{config.
check(
"prompt_file")};
42 std::string prompt_file_fullpath = resource_finder.
findFile(config.
find(
"prompt_file").asString());
43 auto stream = std::ifstream(prompt_file_fullpath);
46 yWarning() <<
"File:" << prompt_file_fullpath <<
"does not exist or path is invalid";
50 std::ostringstream sstr;
51 sstr << stream.rdbuf();
59 bool has_function_file{config.
check(
"functions_file")};
64 std::string functions_file_fullpath = resource_finder.
findFile(config.
find(
"functions_file").asString());
65 auto stream = std::ifstream(functions_file_fullpath);
68 yWarning() <<
"File: " << functions_file_fullpath <<
"does not exist or path is invalid.";
74 json function_js = json::parse(stream);
75 if (!setFunctions(function_js))
88 m_convo->AddUserData(question);
93 yWarning() <<
"Device in offline mode";
100 liboai::Response res = oai.Azure->create_chat_completion(
101 azure_resource, azure_deployment_id, azure_api_version,
103 m_convo->Update(res);
105 catch (
const std::exception &e)
107 yError() << e.what() <<
'\n';
111 if(m_convo->LastResponseIsFunctionCall())
113 yDebug() <<
"Last answer was function call";
114 auto str_args = m_convo->GetLastFunctionCallArguments();
115 std::string function_call_name = m_convo->GetLastFunctionCallName();
116 auto j_args = json::parse(str_args);
118 std::vector<std::string> parameters_list;
119 std::vector<std::string> arguments_list;
121 for(
const auto&[key,val]: j_args.items())
123 parameters_list.push_back(key);
124 arguments_list.push_back(val);
132 m_function_called.insert({m_convo_length,function_call_message});
134 oAnswer = function_call_message;
139 m_convo->GetLastResponse(),
140 std::vector<std::string>(),
141 std::vector<std::string>()};
145 return yarp::dev::ReturnValue_ok;
155 yError() <<
"A prompt is already set. You must delete conversation first";
161 m_convo->SetSystemData(prompt);
163 catch (
const std::exception &e)
165 yError() << e.what() <<
'\n';
169 return yarp::dev::ReturnValue_ok;
174 auto &convo_json = m_convo->GetJSON();
175 for (
auto &message : convo_json[
"messages"])
177 if (message[
"role"] ==
"system")
179 oPrompt = message[
"content"];
180 return yarp::dev::ReturnValue_ok;
189 std::vector<yarp::dev::LLM_Message> conversation;
191 auto &convo_json = m_convo->GetJSON();
194 if (convo_json[
"messages"].empty())
196 yWarning() <<
"Conversation is empty!";
200 for (
auto &message : convo_json[
"messages"])
202 std::string type = message[
"role"].get<std::string>();
203 std::string content = message[
"content"].get<std::string>();
205 conversation.push_back(
yarp::dev::LLM_Message{type, content,std::vector<std::string>(),std::vector<std::string>()});
209 for(
const auto& [i,answer]: m_function_called)
211 auto conv_it = conversation.begin();
212 conversation.insert(std::next(conv_it,i),answer);
215 oConversation = conversation;
216 return yarp::dev::ReturnValue_ok;
222 m_convo.reset(
new liboai::Conversation());
224 m_function_called.clear();
225 return yarp::dev::ReturnValue_ok;
230 std::string current_prompt =
"";
234 return yarp::dev::ReturnValue_ok;
242bool GPTDevice::setFunctions(
const json& function_json)
245 for (
auto& function: function_json.items())
247 if(!function.value().contains(
"name") || !function.value().contains(
"description"))
249 yError() <<
"Function missing mandatory parameters <name> and/or <description>";
253 std::string function_name = function.value()[
"name"].template get<std::string>();
254 std::string function_desc = function.value()[
"description"].template get<std::string>();
256 if(!m_functions->AddFunction(function_name))
258 yError() << module_name +
"::setFunctions(). Cannot add function.";
262 if(!m_functions->SetDescription(function_name,function_desc))
264 yError() << module_name +
"::setFunctions(). Cannot set description";
268 if(function.value().contains(
"parameters"))
270 auto parameters = function.value()[
"parameters"][
"properties"];
271 std::vector<liboai::Functions::FunctionParameter> parameters_vec;
272 for(
auto& params: parameters.items())
274 liboai::Functions::FunctionParameter param;
275 param.name = params.key();
276 param.description = params.value()[
"description"];
277 param.type = params.value()[
"type"];
278 parameters_vec.push_back(param);
280 if(!m_functions->SetParameters(function_name,parameters_vec))
282 yError() << module_name +
"::setFunction(). Cannot set parameters";
288 if(!m_convo->SetFunctions(*m_functions))
290 yError() << module_name +
"::setFunction(). Cannot set function";
yarp::dev::ReturnValue deleteConversation() noexcept override
Delete the conversation and clear the system context from any internally stored context.
yarp::dev::ReturnValue setPrompt(const std::string &prompt) override
Performs a question.
yarp::dev::ReturnValue getConversation(std::vector< yarp::dev::LLM_Message > &oConversation) override
Retrieves the whole conversation.
yarp::dev::ReturnValue refreshConversation() noexcept override
Refresh the conversation.
yarp::dev::ReturnValue readPrompt(std::string &oPrompt) override
Retrieves the provided prompt.
yarp::dev::ReturnValue ask(const std::string &question, yarp::dev::LLM_Message &oAnswer) override
Performs a question.
bool close() override
Close the DeviceDriver.
bool open(yarp::os::Searchable &config) override
Open the DeviceDriver.
@ return_value_error_method_failed
Method is deprecated.
Helper class for finding config files and other external resources.
bool setDefaultContext(const std::string &contextName)
Sets the context for the current ResourceFinder object.
std::string findFile(const std::string &name)
Find the full path to a file.
A base class for nested structures that can be searched.
virtual bool check(const std::string &key) const =0
Check if there exists a property of the given name.
virtual Value & find(const std::string &key) const =0
Gets a value corresponding to a given keyword.
A single value (typically within a Bottle).