Prompt Tools 0.3.2
Loading...
Searching...
No Matches
prompt_bridge.hpp
Go to the documentation of this file.
1#pragma once
2
3#include <uuid/uuid.h>
4
5#include <functional>
6#include <memory>
7#include <pluginlib/class_loader.hpp>
11#include <prompt_msgs/msg/prompt_history.hpp>
12#include <prompt_msgs/msg/prompt_transaction.hpp>
13#include <prompt_msgs/srv/embedding.hpp>
14#include <prompt_msgs/srv/prompt.hpp>
15#include <prompt_msgs/srv/tokenize.hpp>
16#include <rclcpp/rclcpp.hpp>
17#include <thread>
18
19namespace prompt
20{
28class PromptBridge : public rclcpp::Node
29{
30 using PromptSrv = prompt_msgs::srv::Prompt;
31 using EmbeddingSrv = prompt_msgs::srv::Embedding;
32 using TokenizeSrv = prompt_msgs::srv::Tokenize;
33
34public:
40 PromptBridge(const rclcpp::NodeOptions& options = rclcpp::NodeOptions())
41 : Node("prompt_bridge", options)
42 , prompt_loader("prompt_bridge", "prompt::BaseClass")
43 , embedding_loader("prompt_bridge", "prompt::BaseClass")
44 , tokenizer_loader("prompt_bridge", "prompt::BaseClass")
45 {
46 try
47 {
48 if (shared_from_this())
49 {
50 initialize();
51 }
52 }
53 catch (const std::bad_weak_ptr&)
54 {
55 // Not yet safe — probably standalone without make_shared
56 }
57 }
58
65 {
66 /*************************************************************************
67 * Declare parameters
68 ************************************************************************/
69
70 this->declare_parameter("frame_id", "agent");
71 this->declare_parameter("cached_transactions", 10);
72
73 frame_id_ = this->get_parameter("frame_id").as_string();
74 transaction_limit_ = this->get_parameter("cached_transactions").as_int();
75
76 /*************************************************************************
77 * load prompt family plugins
78 ************************************************************************/
79
80 this->declare_parameter("prompt_family_names", rclcpp::ParameterValue(std::vector<std::string>{}));
81 prompt_families_keys_ = this->get_parameter("prompt_family_names").as_string_array();
82
83 for (const auto& family_key : prompt_families_keys_)
84 {
85 this->declare_parameter("prompt_family_plugins." + family_key, rclcpp::ParameterValue(""));
86 std::string plugin = this->get_parameter("prompt_family_plugins." + family_key).as_string();
87 prompt_families_names_[family_key] = plugin;
88 }
89
90 /*************************************************************************
91 * load embedding family plugins
92 ************************************************************************/
93
94 this->declare_parameter("embedding_family_names", rclcpp::ParameterValue(std::vector<std::string>{}));
95 embedding_families_keys_ = this->get_parameter("embedding_family_names").as_string_array();
96
97 for (const auto& family_key : embedding_families_keys_)
98 {
99 this->declare_parameter("embedding_family_plugins." + family_key, rclcpp::ParameterValue(""));
100 std::string plugin = this->get_parameter("embedding_family_plugins." + family_key).as_string();
101 embedding_families_names_[family_key] = plugin;
102 }
103
104 /*************************************************************************
105 * load tokenizer family plugins
106 ************************************************************************/
107
108 this->declare_parameter("tokenizer_family_names", rclcpp::ParameterValue(std::vector<std::string>{}));
109 tokenizer_families_keys_ = this->get_parameter("tokenizer_family_names").as_string_array();
110
111 for (const auto& family_key : tokenizer_families_keys_)
112 {
113 this->declare_parameter("tokenizer_family_plugins." + family_key, rclcpp::ParameterValue(""));
114 std::string plugin = this->get_parameter("tokenizer_family_plugins." + family_key).as_string();
115 tokenizer_families_names_[family_key] = plugin;
116 }
117
118 /*************************************************************************
119 * prompt history ros interfaces
120 ************************************************************************/
121
122 // history publisher
123 prompt_history_pub_ = this->create_publisher<prompt_msgs::msg::PromptHistory>("prompt/history", 1);
124
125 // history publisher timer
127 this->create_wall_timer(std::chrono::duration<double>(1.0), std::bind(&PromptBridge::history_timer, this));
128
129 /*************************************************************************
130 * prompt service ros interfaces
131 ************************************************************************/
132
134 this->create_service<PromptSrv>("prompt/prompt", std::bind(&PromptBridge::prompt_service_cb, this,
135 std::placeholders::_1, std::placeholders::_2));
136 RCLCPP_INFO(this->get_logger(), "Prompt service created at 'prompt/prompt'");
137
139 this->create_service<EmbeddingSrv>("prompt/embedding", std::bind(&PromptBridge::embedding_service_cb, this,
140 std::placeholders::_1, std::placeholders::_2));
141 RCLCPP_INFO(this->get_logger(), "Embedding service created at 'prompt/embedding'");
142
144 this->create_service<TokenizeSrv>("prompt/tokenizer", std::bind(&PromptBridge::tokenize_service_cb, this,
145 std::placeholders::_1, std::placeholders::_2));
146 RCLCPP_INFO(this->get_logger(), "Tokenizer service created at 'prompt/tokenizer'");
147
148 RCLCPP_INFO(this->get_logger(), "PromptBridge initialized");
149 }
150
151 ~PromptBridge() = default;
152
156 static std::string generate_uuid()
157 {
158 uuid_t uuid;
159 uuid_generate_random(uuid);
160 char uuid_str[40];
161 uuid_unparse(uuid, uuid_str);
162 return std::string(uuid_str);
163 }
164
172 std::shared_ptr<prompt::BaseClass> load_prompt_model(std::string family)
173 {
174 std::shared_ptr<prompt::BaseClass> prompt_provider_instance_;
175
176 // check if the prompt family exists
177 if (prompt_families_names_.find(family) != prompt_families_names_.end())
178 {
179 prompt_provider_instance_ = prompt_loader.createSharedInstance(prompt_families_names_[family]);
180 prompt_provider_instance_->initialize(shared_from_this());
181
182 return prompt_provider_instance_;
183 }
184 else
185 {
186 RCLCPP_ERROR(this->get_logger(), "Prompt family not found");
187 throw prompt::PromptException("Prompt family not found");
188 }
189 }
190
199 std::shared_ptr<prompt::BaseClass> load_embedding_model(std::string family)
200 {
201 std::shared_ptr<prompt::BaseClass> embed_provider_instance_;
202
203 // check if the prompt family exists
205 {
206 embed_provider_instance_ = embedding_loader.createSharedInstance(embedding_families_names_[family]);
207 embed_provider_instance_->initialize(shared_from_this());
208
209 return embed_provider_instance_;
210 }
211 else
212 {
213 RCLCPP_ERROR(this->get_logger(), "Embedding family not found");
214 throw prompt::PromptException("Embedding family not found");
215 }
216 }
217
226 std::shared_ptr<prompt::BaseClass> load_tokenizer_model(std::string family)
227 {
228 std::shared_ptr<prompt::BaseClass> tokenizer_provider_instance_;
229
230 // check if the prompt family exists
232 {
233 tokenizer_provider_instance_ = tokenizer_loader.createSharedInstance(tokenizer_families_names_[family]);
234 tokenizer_provider_instance_->initialize(shared_from_this());
235
236 return tokenizer_provider_instance_;
237 }
238 else
239 {
240 RCLCPP_ERROR(this->get_logger(), "Tokenizer family not found");
241 throw prompt::PromptException("Tokenizer family not found");
242 }
243 }
244
257 void prompt_service_cb(const std::shared_ptr<PromptSrv::Request> req, std::shared_ptr<PromptSrv::Response> res)
258 {
259 // prompt provider
260 std::shared_ptr<prompt::BaseClass> prompt_provider_;
261 try
262 {
263 prompt_provider_ = load_prompt_model(req->prompt.model_family);
264 }
265 catch (const prompt::PromptException& e)
266 {
267 RCLCPP_ERROR(this->get_logger(), "Failed to load model: %s", e.what());
268 res->response.success = false;
269 res->response.response = "Failed to load model: " + std::string(e.what());
270 return;
271 }
272 catch (const std::exception& e)
273 {
274 RCLCPP_ERROR(this->get_logger(), "Unexpected error while loading model: %s", e.what());
275 res->response.success = false;
276 res->response.response = "Unexpected error while loading model: " + std::string(e.what());
277 return;
278 }
279
280 try
281 {
282 std::string uuid;
283
284 prompt::PromptRequest input = prompt::fromMsg(req->prompt);
286
287 // pre send time
288 auto pre_send_time = this->now();
289
290 // check if chat mode is enabled
291 if (req->prompt.use_chat_mode)
292 {
293 // chat mode is enabled. requests and response are part of a conversation and they are stored accordingly.
294 // check if this is a new prompt or a continuation of a previous prompt
295 if (req->uuid == "")
296 {
297 // since uuid is empty, This is a new prompt request. Check if caching is requested.
298 if (req->prompt.use_cache)
299 {
300 // new prompt with caching requested. check if flushing cache is requested
301 if (req->prompt.flush_cache)
302 {
303 // flushing cache on new prompt doesn't make sense, log a warning and process the prompt directly
304 RCLCPP_WARN(this->get_logger(), "Flushing cache requested on new prompt with no uuid. Prompt will be "
305 "processed without caching.");
306
307 // continue caching, generate a new uuid for tracking
308 result = prompt_provider_->sendPrompt(input);
309 result.buffered = false;
310
311 // generate a new uuid for tracking since chat mode is enabled
312 uuid = generate_uuid();
313
314 // store the user prompt in the conversation history
315 PromptDialogue dialogue;
316 dialogue.role = "user";
317 dialogue.content = req->prompt.prompt;
318 prompt_conversations_[uuid].push_back(dialogue);
319
320 // store the assistant response in the conversation history
321 PromptDialogue dialogue2;
322 dialogue2.role = "assistant";
323 dialogue2.content = result.response;
324 prompt_conversations_[uuid].push_back(dialogue2);
325
326 // convert the result to message and return the uuid to the client for future reference
327 res->response = prompt::toMsg(result);
328 res->uuid = uuid;
329 RCLCPP_INFO(this->get_logger(), "New chat prompt processed. Generated UUID: %s", uuid.c_str());
330 }
331 else
332 {
333 // continue caching, generate a new uuid for tracking
334 uuid = generate_uuid();
335
336 PromptDialogue dialogue;
337 dialogue.role = "user";
338 dialogue.content = req->prompt.prompt;
339 prompt_conversations_[uuid].push_back(dialogue);
340
341 result.buffered = true;
342
343 // convert the result to message and return the uuid to the client for future reference
344 res->response = prompt::toMsg(result);
345 res->uuid = uuid;
346
347 RCLCPP_INFO(this->get_logger(), "New chat prompt cached. Generated UUID: %s", uuid.c_str());
348 }
349 }
350 else
351 {
352 // no caching, process the prompt directly
353 // generate a new uuid for tracking since chat mode is enabled
354 uuid = generate_uuid();
355
356 // no caching required, process the prompt directly
357 result = prompt_provider_->sendPrompt(input);
358 result.buffered = false;
359
360 // store the user prompt in the conversation history
361 PromptDialogue dialogue;
362 dialogue.role = "user";
363 dialogue.content = req->prompt.prompt;
364 prompt_conversations_[uuid].push_back(dialogue);
365
366 // store the assistant response in the conversation history
367 PromptDialogue dialogue2;
368 dialogue2.role = "assistant";
369 dialogue2.content = result.response;
370 prompt_conversations_[uuid].push_back(dialogue2);
371
372 // convert the result to message and return the uuid to the client for future reference
373 res->response = prompt::toMsg(result);
374 res->uuid = uuid;
375
376 RCLCPP_INFO(this->get_logger(), "New chat prompt processed. Generated UUID: %s", uuid.c_str());
377 }
378 }
379 else
380 {
381 // Since uuid is provided, this is a continuation of a previous prompt request
382 if (req->prompt.use_cache)
383 {
384 if (req->prompt.flush_cache)
385 {
386 // flushing the cache, retrieve the conversation history using the provided uuid
387 uuid = req->uuid;
388
389 // prompt the provider with the conversation history
390 result = prompt_provider_->sendConversation(input, prompt_conversations_[uuid]);
391 result.buffered = false;
392
393 // store the user prompt in the conversation history
394 PromptDialogue dialogue;
395 dialogue.role = "user";
396 dialogue.content = req->prompt.prompt;
397 prompt_conversations_[uuid].push_back(dialogue);
398
399 // store the assistant response in the conversation history
400 PromptDialogue dialogue2;
401 dialogue2.role = "assistant";
402 dialogue2.content = result.response;
403 prompt_conversations_[uuid].push_back(dialogue2);
404
405 // convert the result to message and return the uuid to the client for future reference
406 res->response = prompt::toMsg(result);
407 res->uuid = uuid;
408 RCLCPP_INFO(this->get_logger(), "Chat prompt processed with flushed cache. UUID: %s", uuid.c_str());
409 }
410 else
411 {
412 // continue caching, retrieve the conversation history using the provided uuid
413 uuid = req->uuid;
414
415 // find the last dialogue related to the uuid from conversation and update the prompt in order to cache
416 auto conv_it = prompt_conversations_.find(uuid);
417 if (conv_it != prompt_conversations_.end() && !conv_it->second.empty())
418 {
419 conv_it->second.back().content += " " + req->prompt.prompt;
420 }
421 else
422 {
423 // If the UUID is unknown or has no history, start a new dialogue entry instead of
424 // accessing back() on an empty conversation, which would be undefined behavior.
425 PromptDialogue dialogue;
426 dialogue.role = "user";
427 dialogue.content = req->prompt.prompt;
428 prompt_conversations_[uuid].push_back(dialogue);
429 }
430 result.buffered = true;
431
432 // convert the result to message and return the uuid to the client for future reference
433 res->response = prompt::toMsg(result);
434 res->uuid = uuid;
435
436 RCLCPP_INFO(this->get_logger(), "Chat prompt cached. UUID: %s", uuid.c_str());
437 }
438 }
439 else
440 {
441 // no caching, process the prompt directly.
442 // retrieve the conversation history using the provided uuid
443 uuid = req->uuid;
444
445 // prompt the provider with the conversation history
446 result = prompt_provider_->sendConversation(input, prompt_conversations_[uuid]);
447 result.buffered = false;
448
449 // store the user prompt in the conversation history
450 PromptDialogue dialogue;
451 dialogue.role = "user";
452 dialogue.content = req->prompt.prompt;
453 prompt_conversations_[uuid].push_back(dialogue);
454
455 // store the assistant response in the conversation history
456 PromptDialogue dialogue2;
457 dialogue2.role = "assistant";
458 dialogue2.content = result.response;
459 prompt_conversations_[uuid].push_back(dialogue2);
460
461 // convert the result to message and return the uuid to the client for future reference
462 res->response = prompt::toMsg(result);
463 res->uuid = uuid;
464
465 RCLCPP_INFO(this->get_logger(), "Chat prompt processed. UUID: %s", uuid.c_str());
466 }
467 }
468 }
469 else
470 {
471 // chat mode is not enabled, process the prompt individually. check if this is a new prompt or
472 // a continuation of caching of a previous prompt. Since chat mode is not enabled, caching is only
473 // used to collect inputs from multiple sources and only containes the role of "user".
474 if (req->uuid == "")
475 {
476 // since uuid is empty, This is a new prompt request. Check if caching is requested.
477 if (req->prompt.use_cache)
478 {
479 if (req->prompt.flush_cache)
480 {
481 // flushing cache on new prompt doesn't make sense, log a warning and process prompt immediately
482 RCLCPP_WARN(this->get_logger(), "Flushing cache requested on new prompt with no uuid. Prompt will be "
483 "processed without caching.");
484
485 // continue caching, generate a new uuid for tracking
486 result = prompt_provider_->sendPrompt(input);
487 result.buffered = false;
488
489 res->response = prompt::toMsg(result);
490 res->uuid = "";
491 RCLCPP_INFO(this->get_logger(), "New chat prompt processed. No UUID generated due to flush request and "
492 "disabled chat mode");
493 }
494 else
495 {
496 // no flush request thus continue caching, since uuid is not provided, generate a new uuid for tracking
497 uuid = generate_uuid();
498
499 PromptDialogue dialogue;
500 dialogue.role = "user";
501 dialogue.content = req->prompt.prompt;
502
503 prompt_conversations_[uuid].push_back(dialogue);
504
505 result.buffered = true;
506
507 // convert the result to message and return the uuid to the client for future reference
508 res->response = prompt::toMsg(result);
509 res->uuid = uuid;
510
511 RCLCPP_INFO(this->get_logger(), "New prompt cached. Generated UUID: %s", uuid.c_str());
512 }
513 }
514 else
515 {
516 // no caching, and no uuid. process the prompt directly. since chat mode is not enabled,
517 // no need to store the prompt in conversation history. not required to return a uuid either.
518 result = prompt_provider_->sendPrompt(input);
519 result.buffered = false;
520
521 // convert the result to message and return
522 res->response = prompt::toMsg(result);
523 res->uuid = "";
524 RCLCPP_INFO(this->get_logger(), "New prompt processed.");
525 }
526 }
527 else
528 {
529 // since uuid is provided, this is a continuation of a previous prompt request. since chat mode is not enabled,
530 // the conversation history only contains "user" role prompts and using caching to collect multiple inputs.
531 if (req->prompt.use_cache)
532 {
533 if (req->prompt.flush_cache)
534 {
535 // flushing the cache, retrieve the conversation history using the provided uuid
536 uuid = req->uuid;
537
538 // check if the uuid exists in the conversation history. if not, log a warning and process the prompt
539 // directly since there's no conversation history to flush
540 if (prompt_conversations_.find(uuid) == prompt_conversations_.end())
541 {
542 RCLCPP_WARN(this->get_logger(), "UUID provided for flush request does not exist in conversation history. "
543 "Processing prompt directly.");
544 result = prompt_provider_->sendPrompt(input);
545 result.buffered = false;
546
547 // convert the result to message and discontinue the uuid since chat mode disabled
548 res->response = prompt::toMsg(result);
549 res->uuid = "";
550 return;
551 }
552
553 result = prompt_provider_->sendConversation(input, prompt_conversations_[uuid]);
554 result.buffered = false;
555
556 // convert the result to message and discontinue the uuid since chat mode disabled
557 res->response = prompt::toMsg(result);
558 res->uuid = "";
559
560 RCLCPP_INFO(this->get_logger(), "Prompt processed with flushed cache. UUID: %s discontinued.",
561 uuid.c_str());
562 }
563 else
564 {
565 // flushing not requested, continue caching, retrieve the conversation history using the provided uuid
566 uuid = req->uuid;
567
568 // check if the uuid exists in the conversation history. if not, log a warning and start a new cache with
569 // the provided uuid
570 if (prompt_conversations_.find(uuid) == prompt_conversations_.end())
571 {
572 RCLCPP_WARN(this->get_logger(), "uuid : %s does not exist in cache. Starting new cache", uuid.c_str());
573 PromptDialogue dialogue;
574 dialogue.role = "user";
575 dialogue.content = req->prompt.prompt;
576 prompt_conversations_[uuid].push_back(dialogue);
577 result.buffered = true;
578 }
579 else
580 {
581 // get the last dialogue from the conversation and append the new prompt to that for caching
582 prompt_conversations_[uuid].back().content += " " + req->prompt.prompt;
583 result.buffered = true;
584 }
585
586 // convert the (buffered-only) result to a message and return the same UUID so the client can continue
587 res->response = prompt::toMsg(result);
588 res->uuid = uuid;
589
590 RCLCPP_INFO(this->get_logger(), "Prompt cached without flushing in non-chat mode. UUID: %s.", uuid.c_str());
591 }
592 }
593 else
594 {
595 // no use of cache, chat mode is not enabled, process the prompt directly. No use in uuid either. ignore the
596 // uuid provided and process the prompt directly. give a warning.
597 RCLCPP_WARN(this->get_logger(), "UUID provided for non-chat prompt with no caching. Ignoring UUID and "
598 "processing as a generic prompt");
599
600 result = prompt_provider_->sendPrompt(input);
601 result.buffered = false;
602
603 // convert the result to message and return
604 res->response = prompt::toMsg(result);
605 res->uuid = "";
606 RCLCPP_INFO(this->get_logger(), "Prompt processed.");
607 }
608 }
609 }
610
611 update_prompt_history(req->prompt, res->response, pre_send_time, this->now());
612 }
613 catch (const prompt::PromptException& e)
614 {
615 RCLCPP_ERROR(this->get_logger(), "Prompt request failed: %s", e.what());
616 res->response.success = false;
617 res->response.buffered = false;
618 res->response.response = std::string("Prompt request failed: ") + e.what();
619 res->uuid.clear();
620 }
621 catch (const std::exception& e)
622 {
623 RCLCPP_ERROR(this->get_logger(), "Unexpected prompt request failure: %s", e.what());
624 res->response.success = false;
625 res->response.buffered = false;
626 res->response.response = std::string("Unexpected prompt request failure: ") + e.what();
627 res->uuid.clear();
628 }
629 }
630
643 void embedding_service_cb(const std::shared_ptr<EmbeddingSrv::Request> req,
644 std::shared_ptr<EmbeddingSrv::Response> res)
645 {
646 // embedding provider
647 std::shared_ptr<prompt::BaseClass> embedding_provider_;
648 try
649 {
650 embedding_provider_ = load_embedding_model(req->input.model_family);
651 }
652 catch (const prompt::PromptException& e)
653 {
654 RCLCPP_ERROR(this->get_logger(), "Failed to load model: %s", e.what());
655 res->output.success = false;
656 res->output.error = "Failed to load model: " + std::string(e.what());
657 return;
658 }
659 catch (const std::exception& e)
660 {
661 RCLCPP_ERROR(this->get_logger(), "Unexpected error while loading model: %s", e.what());
662 res->output.success = false;
663 res->output.error = "Unexpected error while loading model: " + std::string(e.what());
664 return;
665 }
666
667 try
668 {
669 prompt::EmbedRequest input = prompt::fromMsg(req->input);
671
672 // process the embedding request
673 result = embedding_provider_->get_embeddings(input);
674 res->output = prompt::toMsg(result);
675
676 RCLCPP_INFO(this->get_logger(), "Embedding request processed.");
677 }
678 catch (const prompt::PromptException& e)
679 {
680 RCLCPP_ERROR(this->get_logger(), "Embedding request failed: %s", e.what());
681 res->output.success = false;
682 res->output.error = std::string("Embedding request failed: ") + e.what();
683 }
684 catch (const std::exception& e)
685 {
686 RCLCPP_ERROR(this->get_logger(), "Unexpected embedding request failure: %s", e.what());
687 res->output.success = false;
688 res->output.error = std::string("Unexpected embedding request failure: ") + e.what();
689 }
690 }
691
704 void tokenize_service_cb(const std::shared_ptr<TokenizeSrv::Request> req, std::shared_ptr<TokenizeSrv::Response> res)
705 {
706 // tokenizer provider
707 std::shared_ptr<prompt::BaseClass> tokenizer_provider_;
708 try
709 {
710 tokenizer_provider_ = load_tokenizer_model(req->input.model_family);
711 }
712 catch (const prompt::PromptException& e)
713 {
714 RCLCPP_ERROR(this->get_logger(), "Failed to load model: %s", e.what());
715 res->output.success = false;
716 res->output.error = "Failed to load model: " + std::string(e.what());
717 return;
718 }
719 catch (const std::exception& e)
720 {
721 RCLCPP_ERROR(this->get_logger(), "Unexpected error while loading model: %s", e.what());
722 res->output.success = false;
723 res->output.error = "Unexpected error while loading model: " + std::string(e.what());
724 return;
725 }
726
727 try
728 {
729 prompt::TokenRequest input = prompt::fromMsg(req->input);
731
732 // process the tokenization request
733 result = tokenizer_provider_->get_tokens(input);
734 res->output = prompt::toMsg(result);
735
736 RCLCPP_INFO(this->get_logger(), "Tokenization request processed.");
737 }
738 catch (const prompt::PromptException& e)
739 {
740 RCLCPP_ERROR(this->get_logger(), "Tokenization request failed: %s", e.what());
741 res->output.success = false;
742 res->output.error = std::string("Tokenization request failed: ") + e.what();
743 }
744 catch (const std::exception& e)
745 {
746 RCLCPP_ERROR(this->get_logger(), "Unexpected tokenization request failure: %s", e.what());
747 res->output.success = false;
748 res->output.error = std::string("Unexpected tokenization request failure: ") + e.what();
749 }
750 }
751
752private:
758 {
759 // publish the prompt history
760 prompt_history_.header.frame_id = frame_id_;
761 prompt_history_.header.stamp = this->now();
763 }
764
773 void update_prompt_history(prompt_msgs::msg::Prompt prompt, prompt_msgs::msg::PromptResponse response,
774 rclcpp::Time prompt_time, rclcpp::Time response_time)
775 {
776 // create the prompt transaction
777 prompt_msgs::msg::PromptTransaction prompt_transaction = prompt_msgs::msg::PromptTransaction();
778
779 prompt_transaction.prompt.header = std_msgs::msg::Header();
780 prompt_transaction.prompt.header.stamp = prompt_time;
781 prompt_transaction.prompt.prompt = prompt;
782 prompt_transaction.response.header = std_msgs::msg::Header();
783 prompt_transaction.response.header.stamp = response_time;
784 prompt_transaction.response.response = response;
785
786 // update the prompt history
787 prompt_history_.transactions.push_back(prompt_transaction);
788
789 // remove old transactions
790 while (prompt_history_.transactions.size() > transaction_limit_)
791 {
792 prompt_history_.transactions.erase(prompt_history_.transactions.begin());
793 }
794 }
795
796private:
797 std::string frame_id_; // frame id
798 unsigned int transaction_limit_; // number of transactions stored in history
799
800 std::string provider_name_;
801
802 // prompt history
803 prompt_msgs::msg::PromptHistory prompt_history_;
804
805 // loaders
806 pluginlib::ClassLoader<prompt::BaseClass> prompt_loader;
807 pluginlib::ClassLoader<prompt::BaseClass> embedding_loader;
808 pluginlib::ClassLoader<prompt::BaseClass> tokenizer_loader;
809
810 // pubs
811 rclcpp::Publisher<prompt_msgs::msg::PromptHistory>::SharedPtr prompt_history_pub_;
812
813 // services
814 rclcpp::Service<PromptSrv>::SharedPtr prompt_service_;
815 rclcpp::Service<EmbeddingSrv>::SharedPtr embedding_service_;
816 rclcpp::Service<TokenizeSrv>::SharedPtr tokenizer_service_;
817
818 // timers
819 rclcpp::TimerBase::SharedPtr history_pub_timer_;
820
821 // prompt families
822 std::vector<std::string> prompt_families_keys_;
823 std::map<std::string, std::string> prompt_families_names_;
824
825 // embedding families
826 std::vector<std::string> embedding_families_keys_;
827 std::map<std::string, std::string> embedding_families_names_;
828
829 // tokenizer families
830 std::vector<std::string> tokenizer_families_keys_;
831 std::map<std::string, std::string> tokenizer_families_names_;
832
833 // prompt conversations
834 std::map<std::string, std::vector<prompt::PromptDialogue>> prompt_conversations_;
835};
836
837} // namespace prompt
PromptBridge.
Definition prompt_bridge.hpp:29
std::vector< std::string > prompt_families_keys_
Definition prompt_bridge.hpp:822
std::map< std::string, std::string > embedding_families_names_
Definition prompt_bridge.hpp:827
rclcpp::Publisher< prompt_msgs::msg::PromptHistory >::SharedPtr prompt_history_pub_
Definition prompt_bridge.hpp:811
rclcpp::Service< PromptSrv >::SharedPtr prompt_service_
Definition prompt_bridge.hpp:814
std::map< std::string, std::string > tokenizer_families_names_
Definition prompt_bridge.hpp:831
void history_timer()
Timer callback to publish prompt history at regular intervals.
Definition prompt_bridge.hpp:757
rclcpp::TimerBase::SharedPtr history_pub_timer_
Definition prompt_bridge.hpp:819
unsigned int transaction_limit_
Definition prompt_bridge.hpp:798
void embedding_service_cb(const std::shared_ptr< EmbeddingSrv::Request > req, std::shared_ptr< EmbeddingSrv::Response > res)
embedding service callback for embedding requests
Definition prompt_bridge.hpp:643
pluginlib::ClassLoader< prompt::BaseClass > tokenizer_loader
Definition prompt_bridge.hpp:808
prompt_msgs::msg::PromptHistory prompt_history_
Definition prompt_bridge.hpp:803
static std::string generate_uuid()
Generate a UUID string for prompt tracking.
Definition prompt_bridge.hpp:156
std::map< std::string, std::vector< prompt::PromptDialogue > > prompt_conversations_
Definition prompt_bridge.hpp:834
pluginlib::ClassLoader< prompt::BaseClass > prompt_loader
Definition prompt_bridge.hpp:806
rclcpp::Service< TokenizeSrv >::SharedPtr tokenizer_service_
Definition prompt_bridge.hpp:816
prompt_msgs::srv::Embedding EmbeddingSrv
Definition prompt_bridge.hpp:31
void prompt_service_cb(const std::shared_ptr< PromptSrv::Request > req, std::shared_ptr< PromptSrv::Response > res)
prompt service callback for instance prompts
Definition prompt_bridge.hpp:257
std::vector< std::string > embedding_families_keys_
Definition prompt_bridge.hpp:826
std::map< std::string, std::string > prompt_families_names_
Definition prompt_bridge.hpp:823
std::string provider_name_
Definition prompt_bridge.hpp:800
pluginlib::ClassLoader< prompt::BaseClass > embedding_loader
Definition prompt_bridge.hpp:807
prompt_msgs::srv::Prompt PromptSrv
Definition prompt_bridge.hpp:30
rclcpp::Service< EmbeddingSrv >::SharedPtr embedding_service_
Definition prompt_bridge.hpp:815
std::shared_ptr< prompt::BaseClass > load_prompt_model(std::string family)
Load a prompt model plugin based on the prompt family.
Definition prompt_bridge.hpp:172
prompt_msgs::srv::Tokenize TokenizeSrv
Definition prompt_bridge.hpp:32
std::shared_ptr< prompt::BaseClass > load_tokenizer_model(std::string family)
Load a tokenizer model plugin based on the tokenizer family.
Definition prompt_bridge.hpp:226
void initialize()
Initialize the PromptBridge node.
Definition prompt_bridge.hpp:64
std::vector< std::string > tokenizer_families_keys_
Definition prompt_bridge.hpp:830
std::string frame_id_
Definition prompt_bridge.hpp:797
void update_prompt_history(prompt_msgs::msg::Prompt prompt, prompt_msgs::msg::PromptResponse response, rclcpp::Time prompt_time, rclcpp::Time response_time)
Update the prompt history with a new prompt transaction.
Definition prompt_bridge.hpp:773
std::shared_ptr< prompt::BaseClass > load_embedding_model(std::string family)
Load an embedding model plugin based on the embedding family.
Definition prompt_bridge.hpp:199
void tokenize_service_cb(const std::shared_ptr< TokenizeSrv::Request > req, std::shared_ptr< TokenizeSrv::Response > res)
tokenizer service callback for tokenization requests
Definition prompt_bridge.hpp:704
PromptBridge(const rclcpp::NodeOptions &options=rclcpp::NodeOptions())
Construct a new Prompt Bridge object.
Definition prompt_bridge.hpp:40
Definition exceptions.hpp:10
virtual const char * what() const noexcept override
Definition exceptions.hpp:16
Definition base_class.hpp:8
static const prompt::PromptRequest fromMsg(const prompt_msgs::msg::Prompt &prompt)
Converts prompt_msgs::msg::Prompt into prompt::PromptRequest which is used internally in prompt tools...
Definition conversions.hpp:21
static const prompt_msgs::msg::PromptResponse toMsg(const prompt::PromptResponse &res)
Converts prompt::PromptResponse into prompt_msgs::msg::PromptResponse which is used in ros2 eco syste...
Definition conversions.hpp:90
Definition structs.hpp:46
Definition structs.hpp:61
Definition structs.hpp:17
std::string role
Definition structs.hpp:18
std::string content
Definition structs.hpp:19
Definition structs.hpp:24
Definition structs.hpp:35
bool buffered
Definition structs.hpp:37
std::string response
Definition structs.hpp:36
Definition structs.hpp:71
Definition structs.hpp:80