Prompt Tools 0.3.2
Loading...
Searching...
No Matches
test_prompt.hpp
Go to the documentation of this file.
1#pragma once
2
3#include <rmw/qos_profiles.h>
4
5#include <chrono>
6#include <memory>
7#include <prompt_msgs/msg/embed.hpp>
8#include <prompt_msgs/msg/embed_response.hpp>
9#include <prompt_msgs/msg/model_option.hpp>
10#include <prompt_msgs/msg/prompt.hpp>
11#include <prompt_msgs/msg/prompt_response.hpp>
12#include <prompt_msgs/srv/embedding.hpp>
13#include <prompt_msgs/srv/prompt.hpp>
14#include <prompt_msgs/srv/tokenize.hpp>
15#include <rclcpp/rclcpp.hpp>
16#include <string>
17#include <vector>
18using namespace std::chrono_literals;
19
20namespace prompt_test
21{
22class TestPromptNode : public rclcpp::Node
23{
24public:
25 TestPromptNode() : Node("test_prompt_node")
26 {
27 client_group_ = this->create_callback_group(rclcpp::CallbackGroupType::Reentrant);
28 client_ =
29 this->create_client<prompt_msgs::srv::Prompt>("prompt/prompt", rmw_qos_profile_services_default, client_group_);
30 timer_ = this->create_wall_timer(2s, std::bind(&TestPromptNode::run_tests, this));
31 }
32
33private:
34 void run_tests()
35 {
36 if (!client_->wait_for_service(1s))
37 {
38 RCLCPP_WARN(this->get_logger(), "Prompt service not available yet.");
39 return;
40 }
41 timer_->cancel();
42 RCLCPP_INFO(this->get_logger(), "Running prompt_bridge feature tests...");
43 test_step_ = 1;
44 last_uuid_.clear();
46 }
47
49 {
50 auto req = std::make_shared<prompt_msgs::srv::Prompt::Request>();
51 switch (test_step_)
52 {
53 case 1:
54 req->uuid = "";
55 req->prompt.prompt = "What is the capital of France?";
56 req->prompt.use_cache = false;
57 req->prompt.flush_cache = false;
58 req->prompt.use_chat_mode = false;
59 req->prompt.model_family = "openai";
60 break;
61 case 2:
62 req->uuid = "";
63 req->prompt.prompt = "Hello, who are you?";
64 req->prompt.use_cache = false;
65 req->prompt.flush_cache = false;
66 req->prompt.use_chat_mode = true;
67 req->prompt.model_family = "openai";
68 break;
69 case 3:
70 req->uuid = "";
71 req->prompt.prompt = "Chat cached part one.";
72 req->prompt.use_cache = true;
73 req->prompt.flush_cache = false;
74 req->prompt.use_chat_mode = true;
75 req->prompt.model_family = "openai";
76 break;
77 case 4:
78 req->uuid = last_uuid_;
79 req->prompt.prompt = "Chat cached part two.";
80 req->prompt.use_cache = true;
81 req->prompt.flush_cache = true;
82 req->prompt.use_chat_mode = true;
83 req->prompt.model_family = "openai";
84 break;
85 case 5:
86 req->uuid = "";
87 req->prompt.prompt = "First part of a multi-input.";
88 req->prompt.use_cache = true;
89 req->prompt.flush_cache = false;
90 req->prompt.use_chat_mode = false;
91 req->prompt.model_family = "openai";
92 break;
93 case 6:
94 req->uuid = last_uuid_;
95 req->prompt.prompt = "Flushing cached non-chat prompt.";
96 req->prompt.use_cache = true;
97 req->prompt.flush_cache = true;
98 req->prompt.use_chat_mode = false;
99 req->prompt.model_family = "openai";
100 break;
101 default:
102 return;
103 }
104 RCLCPP_INFO(this->get_logger(), "Sending prompt: %s", req->prompt.prompt.c_str());
105 client_->async_send_request(req, std::bind(&TestPromptNode::handle_response, this, std::placeholders::_1));
106 }
107
108 void handle_response(rclcpp::Client<prompt_msgs::srv::Prompt>::SharedFuture future)
109 {
110 auto res = future.get();
111 RCLCPP_INFO(this->get_logger(), "Response: %s | UUID: %s | Success: %d", res->response.response.c_str(),
112 res->uuid.c_str(), res->response.success);
113 if (test_step_ == 3 || test_step_ == 5)
114 {
115 last_uuid_ = res->uuid;
116 }
117 ++test_step_;
118 if (test_step_ <= 6)
119 {
121 }
122 }
123
124 rclcpp::Client<prompt_msgs::srv::Prompt>::SharedPtr client_;
125 rclcpp::TimerBase::SharedPtr timer_;
126 rclcpp::CallbackGroup::SharedPtr client_group_;
128 std::string last_uuid_;
129};
130
131class TestEmbeddingNode : public rclcpp::Node
132{
133public:
134 TestEmbeddingNode() : Node("test_embedding_node")
135 {
136 client_group_ = this->create_callback_group(rclcpp::CallbackGroupType::Reentrant);
137 client_ = this->create_client<prompt_msgs::srv::Embedding>("prompt/embedding", rmw_qos_profile_services_default,
139 timer_ = this->create_wall_timer(std::chrono::seconds(2), std::bind(&TestEmbeddingNode::run_test, this));
140 }
141
142private:
143 void run_test()
144 {
145 if (!client_->wait_for_service(std::chrono::seconds(1)))
146 {
147 RCLCPP_WARN(this->get_logger(), "Embedding service not available yet.");
148 return;
149 }
150 timer_->cancel();
151 RCLCPP_INFO(this->get_logger(), "Running embedding interface tests (FLOAT + BASE64)...");
152
153 test_step_ = 1;
155 }
156
158 {
159 auto req = std::make_shared<prompt_msgs::srv::Embedding::Request>();
160 req->input.text = "Hello, how are you?";
161 req->input.model_family = "openai";
162
163 if (test_step_ == 1)
164 {
165 prompt_msgs::msg::ModelOption option1;
166 option1.key = "encoding_format";
167 option1.value = "float";
168 option1.type = prompt_msgs::msg::ModelOption::STRING_TYPE;
169
170 req->input.options.push_back(option1);
171 RCLCPP_INFO(this->get_logger(), "Requesting FLOAT embedding format");
172 }
173 else if (test_step_ == 2)
174 {
175 prompt_msgs::msg::ModelOption option2;
176 option2.key = "encoding_format";
177 option2.value = "base64";
178 option2.type = prompt_msgs::msg::ModelOption::STRING_TYPE;
179
180 req->input.options.push_back(option2);
181 RCLCPP_INFO(this->get_logger(), "Requesting BASE64 embedding format");
182 }
183 else
184 {
185 return;
186 }
187
188 client_->async_send_request(req,
189 std::bind(&TestEmbeddingNode::handle_embedding_response, this, std::placeholders::_1));
190 }
191
192 void handle_embedding_response(rclcpp::Client<prompt_msgs::srv::Embedding>::SharedFuture future)
193 {
194 auto res = future.get();
195 const auto& out = res->output;
196 size_t emb_count = out.embeddings.size();
197 int first_index = (emb_count > 0) ? out.embeddings[0].index : -1;
198 bool first_is_float = (emb_count > 0) ? out.embeddings[0].is_float : false;
199 size_t first_float_size = (emb_count > 0) ? out.embeddings[0].float_embedding.size() : 0;
200 size_t first_b64_len = (emb_count > 0) ? out.embeddings[0].base64_embedding.size() : 0;
201
202 RCLCPP_INFO(this->get_logger(),
203 "Embedding response: success=%d, embeddings=%zu, first.index=%d, first.is_float=%d, float.size=%zu, "
204 "base64.len=%zu, model='%s', prompt_tokens=%d, total_tokens=%d, error='%s'",
205 out.success, emb_count, first_index, first_is_float, first_float_size, first_b64_len, out.model.c_str(),
206 out.prompt_tokens, out.total_tokens, out.error.c_str());
207
208 if (!out.success)
209 {
210 RCLCPP_ERROR(this->get_logger(), "Embedding request failed: %s", out.error.c_str());
211 }
212
213 if (test_step_ == 1)
214 {
215 if (emb_count == 0)
216 {
217 RCLCPP_ERROR(this->get_logger(), "Expected at least one embedding in response.");
218 }
219 else if (!out.embeddings[0].is_float)
220 {
221 RCLCPP_ERROR(this->get_logger(), "Expected FLOAT format in response.");
222 }
223 if (out.embeddings[0].float_embedding.empty())
224 {
225 RCLCPP_ERROR(this->get_logger(), "FLOAT embedding array is empty.");
226 }
227 if (!out.embeddings[0].base64_embedding.empty())
228 {
229 RCLCPP_WARN(this->get_logger(), "Base64 embedding should be empty when FLOAT requested.");
230 }
231 }
232 else if (test_step_ == 2)
233 {
234 if (emb_count == 0)
235 {
236 RCLCPP_ERROR(this->get_logger(), "Expected at least one embedding in response.");
237 }
238 else if (out.embeddings[0].is_float)
239 {
240 RCLCPP_ERROR(this->get_logger(), "Expected BASE64 format in response.");
241 }
242 if (out.embeddings[0].base64_embedding.empty())
243 {
244 RCLCPP_ERROR(this->get_logger(), "BASE64 embedding string is empty.");
245 }
246 if (!out.embeddings[0].float_embedding.empty())
247 {
248 RCLCPP_WARN(this->get_logger(), "Float embedding should be empty when BASE64 requested.");
249 }
250 }
251
252 ++test_step_;
253 if (test_step_ <= 2)
254 {
256 }
257 }
258
259 rclcpp::Client<prompt_msgs::srv::Embedding>::SharedPtr client_;
260 rclcpp::TimerBase::SharedPtr timer_;
261 rclcpp::CallbackGroup::SharedPtr client_group_;
262 int test_step_ = 0;
263};
264
265class TestTokenizerNode : public rclcpp::Node
266{
267public:
268 TestTokenizerNode() : Node("test_tokenizer_node")
269 {
270 client_group_ = this->create_callback_group(rclcpp::CallbackGroupType::Reentrant);
271 client_ = this->create_client<prompt_msgs::srv::Tokenize>("prompt/tokenizer", rmw_qos_profile_services_default,
273 timer_ = this->create_wall_timer(std::chrono::seconds(2), std::bind(&TestTokenizerNode::run_test, this));
274 }
275
276private:
277 void run_test()
278 {
279 if (!client_->wait_for_service(std::chrono::seconds(1)))
280 {
281 RCLCPP_WARN(this->get_logger(), "Tokenizer service not available yet.");
282 return;
283 }
284 timer_->cancel();
285 RCLCPP_INFO(this->get_logger(), "Running tokenizer interface tests (ENCODE + DECODE)...");
286 test_step_ = 1;
288 }
289
291 {
292 auto req = std::make_shared<prompt_msgs::srv::Tokenize::Request>();
293 req->input.model_family = "openai";
294 prompt_msgs::msg::ModelOption option;
295 option.key = "model";
296 option.value = "O200K_BASE";
297 option.type = prompt_msgs::msg::ModelOption::STRING_TYPE;
298 req->input.options.push_back(option);
299
300 if (test_step_ == 1)
301 {
302 req->input.text = "Encode this text to tokens.";
303 req->input.encode = true;
304 RCLCPP_INFO(this->get_logger(), "Requesting tokenization (encode) for: %s", req->input.text.c_str());
305 }
306 else if (test_step_ == 2)
307 {
308 req->input.tokens = last_tokens_;
309 req->input.encode = false;
310 RCLCPP_INFO(this->get_logger(), "Requesting detokenization (decode) for %zu tokens.", last_tokens_.size());
311 }
312 else
313 {
314 return;
315 }
316
317 client_->async_send_request(req,
318 std::bind(&TestTokenizerNode::handle_tokenize_response, this, std::placeholders::_1));
319 }
320
321 void handle_tokenize_response(rclcpp::Client<prompt_msgs::srv::Tokenize>::SharedFuture future)
322 {
323 auto res = future.get();
324 const auto& out = res->output;
325 if (!out.success)
326 {
327 RCLCPP_ERROR(this->get_logger(), "Tokenizer request failed: %s", out.error.c_str());
328 return;
329 }
330 if (test_step_ == 1)
331 {
332 last_tokens_ = out.tokens;
333 std::string first_token_str = out.tokens.empty() ? "" : std::to_string(out.tokens[0]);
334 RCLCPP_INFO(this->get_logger(), "Encoded tokens: [%s] (count=%zu)",
335 first_token_str.c_str(), out.tokens.size());
336 for (size_t i = 1; i < out.tokens.size(); ++i)
337 RCLCPP_INFO(this->get_logger(), " token[%zu]=%d", i, out.tokens[i]);
338 ++test_step_;
340 }
341 else if (test_step_ == 2)
342 {
343 RCLCPP_INFO(this->get_logger(), "Decoded text: '%s'", out.text.c_str());
344 }
345 }
346
347 rclcpp::Client<prompt_msgs::srv::Tokenize>::SharedPtr client_;
348 rclcpp::TimerBase::SharedPtr timer_;
349 rclcpp::CallbackGroup::SharedPtr client_group_;
350 int test_step_ = 0;
351 std::vector<int32_t> last_tokens_;
352};
353
354} // namespace prompt_test
Definition test_prompt.hpp:132
TestEmbeddingNode()
Definition test_prompt.hpp:134
rclcpp::CallbackGroup::SharedPtr client_group_
Definition test_prompt.hpp:261
rclcpp::TimerBase::SharedPtr timer_
Definition test_prompt.hpp:260
void send_next_embedding()
Definition test_prompt.hpp:157
void handle_embedding_response(rclcpp::Client< prompt_msgs::srv::Embedding >::SharedFuture future)
Definition test_prompt.hpp:192
rclcpp::Client< prompt_msgs::srv::Embedding >::SharedPtr client_
Definition test_prompt.hpp:259
void run_test()
Definition test_prompt.hpp:143
int test_step_
Definition test_prompt.hpp:262
Definition test_prompt.hpp:23
rclcpp::CallbackGroup::SharedPtr client_group_
Definition test_prompt.hpp:126
int test_step_
Definition test_prompt.hpp:127
void send_next_prompt()
Definition test_prompt.hpp:48
std::string last_uuid_
Definition test_prompt.hpp:128
void run_tests()
Definition test_prompt.hpp:34
void handle_response(rclcpp::Client< prompt_msgs::srv::Prompt >::SharedFuture future)
Definition test_prompt.hpp:108
rclcpp::TimerBase::SharedPtr timer_
Definition test_prompt.hpp:125
TestPromptNode()
Definition test_prompt.hpp:25
rclcpp::Client< prompt_msgs::srv::Prompt >::SharedPtr client_
Definition test_prompt.hpp:124
Definition test_prompt.hpp:266
int test_step_
Definition test_prompt.hpp:350
rclcpp::CallbackGroup::SharedPtr client_group_
Definition test_prompt.hpp:349
TestTokenizerNode()
Definition test_prompt.hpp:268
rclcpp::TimerBase::SharedPtr timer_
Definition test_prompt.hpp:348
std::vector< int32_t > last_tokens_
Definition test_prompt.hpp:351
rclcpp::Client< prompt_msgs::srv::Tokenize >::SharedPtr client_
Definition test_prompt.hpp:347
void send_next_tokenize()
Definition test_prompt.hpp:290
void run_test()
Definition test_prompt.hpp:277
void handle_tokenize_response(rclcpp::Client< prompt_msgs::srv::Tokenize >::SharedFuture future)
Definition test_prompt.hpp:321
Definition test_prompt.hpp:21