test_ChatConversation.js (15418B)
1 /* Any copyright is dedicated to the Public Domain. 2 * http://creativecommons.org/publicdomain/zero/1.0/ */ 3 4 do_get_profile(); 5 6 const { ChatConversation, MESSAGE_ROLE } = ChromeUtils.importESModule( 7 "moz-src:///browser/components/aiwindow/ui/modules/ChatStore.sys.mjs" 8 ); 9 10 const { UserRoleOpts, AssistantRoleOpts, ToolRoleOpts } = 11 ChromeUtils.importESModule( 12 "moz-src:///browser/components/aiwindow/ui/modules/ChatMessage.sys.mjs" 13 ); 14 15 add_task(function test_ChatConversation_constructor_defaults() { 16 const conversation = new ChatConversation({}); 17 18 Assert.withSoftAssertions(function (soft) { 19 soft.equal(conversation.id.length, 12); 20 soft.ok(Array.isArray(conversation.messages)); 21 soft.ok(!isNaN(conversation.createdDate)); 22 soft.ok(!isNaN(conversation.updatedDate)); 23 soft.strictEqual(conversation.title, undefined); 24 soft.strictEqual(conversation.description, undefined); 25 soft.strictEqual(conversation.pageUrl, undefined); 26 soft.strictEqual(conversation.pageMeta, undefined); 27 }); 28 }); 29 30 add_task(function test_ChatConversation_addMessage() { 31 const conversation = new ChatConversation({}); 32 33 const content = { 34 type: "text", 35 content: "hello world", 36 }; 37 38 conversation.addMessage( 39 MESSAGE_ROLE.USER, 40 content, 41 new URL("https://www.mozilla.com"), 42 0 43 ); 44 45 const message = conversation.messages[0]; 46 47 Assert.withSoftAssertions(function (soft) { 48 soft.strictEqual(message.role, MESSAGE_ROLE.USER); 49 soft.strictEqual(message.content, content); 50 soft.strictEqual(message.pageUrl.href, "https://www.mozilla.com/"); 51 soft.strictEqual(message.turnIndex, 0); 52 }); 53 }); 54 55 add_task(function test_invalidRole_ChatConversation_addMessage() { 56 const conversation = new ChatConversation({}); 57 58 const content = { 59 type: "text", 60 content: "hello world", 61 }; 62 63 conversation.addMessage(313, content, new URL("https://www.mozilla.com"), 0); 64 65 Assert.equal(conversation.messages.length, 0); 66 }); 67 68 add_task(function test_negativeTurnIndex_ChatConversation_addMessage() { 69 const conversation = new ChatConversation({}); 70 71 const content = { 72 type: "text", 73 content: "hello world", 74 }; 75 76 conversation.addMessage( 77 MESSAGE_ROLE.USER, 78 content, 79 new URL("https://www.mozilla.com"), 80 -1 81 ); 82 const message = conversation.messages[0]; 83 84 Assert.equal(message.turnIndex, 0); 85 }); 86 87 add_task(function test_parentMessageId_ChatConversation_addMessage() { 88 const conversation = new ChatConversation({}); 89 90 const content = { 91 type: "text", 92 content: "hello world", 93 }; 94 95 conversation.addMessage( 96 MESSAGE_ROLE.USER, 97 content, 98 new URL("https://www.mozilla.com"), 99 0 100 ); 101 102 conversation.addMessage( 103 MESSAGE_ROLE.ASSISTANT, 104 content, 105 new URL("https://www.mozilla.com"), 106 0 107 ); 108 109 const userMsg = conversation.messages[0]; 110 const assistantMsg = conversation.messages[1]; 111 112 Assert.equal(assistantMsg.parentMessageId, userMsg.id); 113 }); 114 115 add_task(function test_ordinal_ChatConversation_addMessage() { 116 const conversation = new ChatConversation({}); 117 118 const content = { 119 type: "text", 120 content: "hello world", 121 }; 122 123 conversation.addMessage( 124 MESSAGE_ROLE.USER, 125 content, 126 new URL("https://www.mozilla.com"), 127 0 128 ); 129 130 conversation.addMessage( 131 MESSAGE_ROLE.ASSISTANT, 132 content, 133 new URL("https://www.mozilla.com"), 134 0 135 ); 136 137 const userMsg = conversation.messages[0]; 138 const assistantMsg = conversation.messages[1]; 139 140 Assert.withSoftAssertions(function (soft) { 141 soft.equal(userMsg.ordinal, 1); 142 soft.equal(assistantMsg.ordinal, 2); 143 }); 144 }); 145 146 add_task(function test_ChatConversation_addUserMessage() { 147 const conversation = new ChatConversation({}); 148 149 const content = "user to assistant msg"; 150 conversation.addUserMessage(content, "https://www.mozilla.com"); 151 152 const message = conversation.messages[0]; 153 154 Assert.withSoftAssertions(function (soft) { 155 soft.equal(message.role, MESSAGE_ROLE.USER); 156 soft.equal(message.turnIndex, 1); 157 soft.deepEqual(message.pageUrl, new URL("https://www.mozilla.com")); 158 soft.deepEqual(message.content, { 159 type: "text", 160 body: "user to assistant msg", 161 }); 162 }); 163 }); 164 165 add_task(function test_revisionRootMessageId_ChatConversation_addUserMessage() { 166 const conversation = new ChatConversation({}); 167 168 const content = "user to assistant msg"; 169 conversation.addUserMessage(content, "https://www.firefox.com"); 170 171 const message = conversation.messages[0]; 172 173 Assert.equal(message.revisionRootMessageId, message.id); 174 }); 175 176 add_task(function test_opts_ChatConversation_addUserMessage() { 177 const conversation = new ChatConversation({}); 178 179 const content = "user to assistant msg"; 180 conversation.addUserMessage( 181 content, 182 "https://www.firefox.com", 183 new UserRoleOpts("321") 184 ); 185 186 const message = conversation.messages[0]; 187 188 Assert.equal(message.revisionRootMessageId, "321"); 189 }); 190 191 add_task(function test_ChatConversation_addAssistantMessage() { 192 const conversation = new ChatConversation({}); 193 194 const content = "response from assistant"; 195 conversation.addAssistantMessage("text", content); 196 197 const message = conversation.messages[0]; 198 199 Assert.withSoftAssertions(function (soft) { 200 soft.equal(message.role, MESSAGE_ROLE.ASSISTANT); 201 soft.equal(message.turnIndex, 0); 202 soft.deepEqual(message.pageUrl, null); 203 soft.deepEqual(message.content, { 204 type: "text", 205 body: "response from assistant", 206 }); 207 soft.strictEqual(message.modelId, null, "modelId should default to false"); 208 soft.strictEqual(message.params, null, "params should default to null"); 209 soft.strictEqual(message.usage, null, "usage should default to null"); 210 soft.strictEqual( 211 message.insightsEnabled, 212 false, 213 "insightsEnabled should default to false" 214 ); 215 soft.strictEqual( 216 message.insightsFlagSource, 217 null, 218 "insightsFlagSource should default to null" 219 ); 220 soft.deepEqual( 221 message.insightsApplied, 222 [], 223 "insightsApplied should default to emtpy array" 224 ); 225 soft.deepEqual( 226 message.webSearchQueries, 227 [], 228 "webSearchQueries should default to emtpy array" 229 ); 230 }); 231 }); 232 233 add_task(function test_opts_ChatConversation_addAssistantMessage() { 234 const conversation = new ChatConversation({}); 235 236 const content = "response from assistant"; 237 const assistantOpts = new AssistantRoleOpts( 238 "the-model-id", 239 { some: "params for model" }, 240 { usage: "data" }, 241 true, 242 1, 243 ["insight"], 244 ["search"] 245 ); 246 conversation.addAssistantMessage("text", content, assistantOpts); 247 248 const message = conversation.messages[0]; 249 250 Assert.withSoftAssertions(function (soft) { 251 soft.equal(message.role, MESSAGE_ROLE.ASSISTANT); 252 soft.equal(message.turnIndex, 0); 253 soft.deepEqual(message.pageUrl, null); 254 soft.deepEqual(message.content, { 255 type: "text", 256 body: "response from assistant", 257 }); 258 soft.strictEqual( 259 message.modelId, 260 "the-model-id", 261 "modelId should be 'the-model-id'" 262 ); 263 soft.deepEqual( 264 message.params, 265 { some: "params for model" }, 266 'params should equal { some: "params for model"}' 267 ); 268 soft.deepEqual( 269 message.usage, 270 { usage: "data" }, 271 'usage should equal {"usage": "data"}' 272 ); 273 soft.strictEqual( 274 message.insightsEnabled, 275 true, 276 "insightsEnabled should equal true" 277 ); 278 soft.strictEqual( 279 message.insightsFlagSource, 280 1, 281 "insightsFlagSource equal 1" 282 ); 283 soft.deepEqual( 284 message.insightsApplied, 285 ["insight"], 286 "insightsApplied should equal ['insight']" 287 ); 288 soft.deepEqual( 289 message.webSearchQueries, 290 ["search"], 291 "insightsApplied should equal ['search']" 292 ); 293 }); 294 }); 295 296 add_task(function test_ChatConversation_addToolCallMessage() { 297 const conversation = new ChatConversation({}); 298 299 const content = { 300 random: "tool call specific keys", 301 }; 302 conversation.addToolCallMessage(content); 303 304 const message = conversation.messages[0]; 305 306 Assert.withSoftAssertions(function (soft) { 307 soft.equal(message.role, MESSAGE_ROLE.TOOL); 308 soft.equal(message.turnIndex, 0); 309 soft.deepEqual(message.pageUrl, null); 310 soft.deepEqual(message.content, { 311 random: "tool call specific keys", 312 }); 313 soft.equal(message.modelId, null, "modelId should default to null"); 314 }); 315 }); 316 317 add_task(function test_opts_ChatConversation_addToolCallMessage() { 318 const conversation = new ChatConversation({}); 319 320 const content = { 321 random: "tool call specific keys", 322 }; 323 conversation.addToolCallMessage(content, new ToolRoleOpts("the-model-id")); 324 325 const message = conversation.messages[0]; 326 327 Assert.withSoftAssertions(function (soft) { 328 soft.equal(message.role, MESSAGE_ROLE.TOOL); 329 soft.equal(message.turnIndex, 0); 330 soft.deepEqual(message.pageUrl, null); 331 soft.deepEqual(message.content, { 332 random: "tool call specific keys", 333 }); 334 soft.equal( 335 message.modelId, 336 "the-model-id", 337 "modelId should equal the-model-id" 338 ); 339 }); 340 }); 341 342 add_task(function test_ChatConversation_addSystemMessage() { 343 const conversation = new ChatConversation({}); 344 345 const content = { 346 random: "system call specific keys", 347 }; 348 conversation.addSystemMessage("text", content); 349 350 const message = conversation.messages[0]; 351 352 Assert.withSoftAssertions(function (soft) { 353 soft.equal(message.role, MESSAGE_ROLE.SYSTEM); 354 soft.equal(message.turnIndex, 0); 355 soft.deepEqual(message.pageUrl, null); 356 soft.deepEqual(message.content, { 357 type: "text", 358 body: { random: "system call specific keys" }, 359 }); 360 }); 361 }); 362 363 add_task(function test_ChatConversation_getSitesList() { 364 const conversation = new ChatConversation({}); 365 366 const content = "user to assistant msg"; 367 conversation.addUserMessage(content, "https://www.mozilla.com"); 368 conversation.addUserMessage(content, "https://www.mozilla.com"); 369 conversation.addUserMessage(content, "https://www.firefox.com"); 370 conversation.addUserMessage(content, "https://www.cnn.com"); 371 conversation.addUserMessage(content, "https://www.espn.com"); 372 conversation.addUserMessage(content, "https://www.espn.com"); 373 374 const sites = conversation.getSitesList(); 375 376 Assert.deepEqual(sites, [ 377 URL.parse("https://www.mozilla.com/"), 378 URL.parse("https://www.firefox.com/"), 379 URL.parse("https://www.cnn.com/"), 380 URL.parse("https://www.espn.com/"), 381 ]); 382 }); 383 384 add_task(function test_ChatConversation_getMostRecentPageVisited() { 385 const conversation = new ChatConversation({}); 386 387 const content = "user to assistant msg"; 388 conversation.addUserMessage(content, "https://www.mozilla.com"); 389 conversation.addUserMessage(content, "https://www.mozilla.com"); 390 conversation.addUserMessage(content, "https://www.firefox.com"); 391 conversation.addUserMessage(content, "https://www.cnn.com"); 392 conversation.addUserMessage(content, "https://www.espn.com"); 393 conversation.addUserMessage(content, "https://www.espn.com"); 394 395 const mostRecentPageVisited = conversation.getMostRecentPageVisited(); 396 397 Assert.equal(mostRecentPageVisited, "https://www.espn.com/"); 398 }); 399 400 add_task(function test_noBrowsing_ChatConversation_getMostRecentPageVisited() { 401 const conversation = new ChatConversation({}); 402 403 const content = "user to assistant msg"; 404 conversation.addUserMessage(content, "about:aiwindow"); 405 conversation.addUserMessage(content, ""); 406 conversation.addUserMessage(content, null); 407 408 const mostRecentPageVisited = conversation.getMostRecentPageVisited(); 409 410 Assert.equal(mostRecentPageVisited, null); 411 }); 412 413 add_task(function test_ChatConversation_renderState() { 414 const conversation = new ChatConversation({}); 415 416 const content = "user to assistant msg"; 417 418 conversation.addUserMessage(content, "about:aiwindow"); 419 conversation.addToolCallMessage("some content"); 420 conversation.addAssistantMessage("text", "a response"); 421 conversation.addUserMessage(content, "about:aiwindow"); 422 conversation.addSystemMessage("text", "some system message"); 423 conversation.addAssistantMessage("text", "a response"); 424 425 const renderState = conversation.renderState(); 426 427 Assert.deepEqual(renderState, [ 428 conversation.messages[0], 429 conversation.messages[2], 430 conversation.messages[3], 431 conversation.messages[5], 432 ]); 433 }); 434 435 add_task(function test_ChatConversation_currentTurnIndex() { 436 const conversation = new ChatConversation({}); 437 438 const content = "user to assistant msg"; 439 440 conversation.addSystemMessage("text", "the system prompt"); 441 conversation.addUserMessage(content, "about:aiwindow"); 442 conversation.addAssistantMessage("text", "a response"); 443 conversation.addUserMessage(content, "about:aiwindow"); 444 conversation.addAssistantMessage("text", "a response"); 445 conversation.addUserMessage(content, "about:aiwindow"); 446 conversation.addAssistantMessage("text", "a response"); 447 conversation.addUserMessage(content, "about:aiwindow"); 448 conversation.addAssistantMessage("text", "a response"); 449 conversation.addUserMessage(content, "about:aiwindow"); 450 conversation.addAssistantMessage("text", "a response"); 451 452 Assert.deepEqual(conversation.currentTurnIndex(), 4); 453 }); 454 455 add_task(function test_ChatConversation_helpersTurnIndexing() { 456 const conversation = new ChatConversation({}); 457 458 conversation.addSystemMessage("text", "the system prompt"); 459 conversation.addUserMessage("a user's prompt", "https://www.somesite.com"); 460 conversation.addToolCallMessage({ some: "tool call details" }); 461 conversation.addAssistantMessage("text", "the llm response"); 462 conversation.addUserMessage( 463 "a user's second prompt", 464 "https://www.somesite.com" 465 ); 466 conversation.addToolCallMessage({ some: "more tool call details" }); 467 conversation.addAssistantMessage("text", "the second llm response"); 468 469 Assert.withSoftAssertions(function (soft) { 470 soft.equal(conversation.messages.length, 7); 471 472 soft.equal(conversation.messages[0].turnIndex, 0); 473 soft.equal(conversation.messages[1].turnIndex, 0); 474 soft.equal(conversation.messages[2].turnIndex, 0); 475 soft.equal(conversation.messages[3].turnIndex, 0); 476 soft.equal(conversation.messages[4].turnIndex, 1); 477 soft.equal(conversation.messages[5].turnIndex, 1); 478 soft.equal(conversation.messages[6].turnIndex, 1); 479 }); 480 }); 481 482 add_task(function test_ChatConversation_getMessagesInOpenAiFormat() { 483 const conversation = new ChatConversation({}); 484 conversation.addSystemMessage("text", "the system prompt"); 485 conversation.addUserMessage("a user's prompt", "https://www.somesite.com"); 486 conversation.addToolCallMessage({ some: "tool call details" }); 487 conversation.addAssistantMessage("text", "the llm response"); 488 conversation.addUserMessage("a user's second prompt", "some question"); 489 conversation.addToolCallMessage({ some: "more tool call details" }); 490 conversation.addAssistantMessage("text", "the second llm response"); 491 492 const openAiFormat = conversation.getMessagesInOpenAiFormat(); 493 494 Assert.deepEqual(openAiFormat, [ 495 { role: "system", content: "the system prompt" }, 496 { role: "user", content: "a user's prompt" }, 497 { role: "tool", content: { some: "tool call details" } }, 498 { role: "assistant", content: "the llm response" }, 499 { role: "user", content: "a user's second prompt" }, 500 { role: "tool", content: { some: "more tool call details" } }, 501 { role: "assistant", content: "the second llm response" }, 502 ]); 503 });