Mercurial
comparison mrjunejune/test/conversation_api_test.js @ 265:056790c4fb0d
add role-aware Epi assistant prompts
Add verified June knowledge, guest/member/admin Copilot profiles, profile-isolated session recovery, animated Epi greetings, and a single authoritative runtime config workflow for inference.
Co-authored-by: Copilot <[email protected]>
| author | MrJuneJune <me@mrjunejune.com> |
|---|---|
| date | Fri, 07 Aug 2026 10:50:30 -0700 |
| parents | 04fee26ecce0 |
| children |
comparison
equal
deleted
inserted
replaced
| 264:04fee26ecce0 | 265:056790c4fb0d |
|---|---|
| 165 ...process.env, | 165 ...process.env, |
| 166 MRJUNEJUNE_PORT: port, | 166 MRJUNEJUNE_PORT: port, |
| 167 MRJUNEJUNE_DB_PATH: databasePath, | 167 MRJUNEJUNE_DB_PATH: databasePath, |
| 168 MRJUNEJUNE_INFERENCE_SIDECAR_PATH: fakeSidecar, | 168 MRJUNEJUNE_INFERENCE_SIDECAR_PATH: fakeSidecar, |
| 169 MRJUNEJUNE_COPILOT_CLI_PATH: fakeSidecar, | 169 MRJUNEJUNE_COPILOT_CLI_PATH: fakeSidecar, |
| 170 MRJUNEJUNE_ALLOW_ANONYMOUS_INFERENCE: '1', | |
| 171 MRJUNEJUNE_ALLOW_GUEST_INFERENCE: '1', | 170 MRJUNEJUNE_ALLOW_GUEST_INFERENCE: '1', |
| 172 }, | 171 }, |
| 173 stdio: ['ignore', 'pipe', 'pipe'], | 172 stdio: ['ignore', 'pipe', 'pipe'], |
| 174 }); | 173 }); |
| 175 server.stdout.on('data', chunk => logs.push(chunk.toString())); | 174 server.stdout.on('data', chunk => logs.push(chunk.toString())); |
| 368 /^text\/event-stream/, | 367 /^text\/event-stream/, |
| 369 ); | 368 ); |
| 370 const stream = await response.text(); | 369 const stream = await response.text(); |
| 371 assert.match(stream, /event: turn\.accepted/); | 370 assert.match(stream, /event: turn\.accepted/); |
| 372 assert.match(stream, /event: tool\.started/); | 371 assert.match(stream, /event: tool\.started/); |
| 373 assert.match(stream, /"tool":\{"name":"mock-search"\}/); | 372 assert.match( |
| 373 stream, | |
| 374 /"tool":\{"name":"mock-search","prompt_profile":"public_visitor"\}/, | |
| 375 ); | |
| 374 assert.match(stream, /event: assistant\.delta/); | 376 assert.match(stream, /event: assistant\.delta/); |
| 375 assert.match(stream, /hello \\"traveler\\"\\\\path/); | 377 assert.match(stream, /hello \\"traveler\\"\\\\path/); |
| 376 assert.match(stream, /event: assistant\.completed/); | 378 assert.match(stream, /event: assistant\.completed/); |
| 377 assert.match(stream, /event: assistant\.usage/); | 379 assert.match(stream, /event: assistant\.usage/); |
| 378 assert.match(stream, /event: turn\.done/); | 380 assert.match(stream, /event: turn\.done/); |
| 495 csrfToken: userCsrfC1, | 497 csrfToken: userCsrfC1, |
| 496 }), | 498 }), |
| 497 }); | 499 }); |
| 498 assert.equal(loginR.status, 200, `Login must succeed, got ${loginR.status}`); | 500 assert.equal(loginR.status, 200, `Login must succeed, got ${loginR.status}`); |
| 499 const userCsrfC2 = await bootstrapSession(claimBase, userJarC); | 501 const userCsrfC2 = await bootstrapSession(claimBase, userJarC); |
| 502 | |
| 503 const assertTurnProfile = async (jar, csrf, expectedProfile, title) => { | |
| 504 const createResponse = await authedFetch( | |
| 505 claimBase, | |
| 506 jar, | |
| 507 csrf, | |
| 508 '/api/conversations', | |
| 509 { | |
| 510 method: 'POST', | |
| 511 headers: { 'Content-Type': 'application/json', Origin: claimBase }, | |
| 512 body: JSON.stringify({ title }), | |
| 513 }, | |
| 514 ); | |
| 515 assert.equal(createResponse.status, 201); | |
| 516 const createdConversation = await createResponse.json(); | |
| 517 const turnResponse = await authedFetch( | |
| 518 claimBase, | |
| 519 jar, | |
| 520 csrf, | |
| 521 `/api/conversations/${createdConversation.id}/turns`, | |
| 522 { | |
| 523 method: 'POST', | |
| 524 headers: { 'Content-Type': 'application/json', Origin: claimBase }, | |
| 525 body: JSON.stringify({ prompt: 'profile check' }), | |
| 526 }, | |
| 527 ); | |
| 528 assert.equal(turnResponse.status, 200); | |
| 529 assert.match( | |
| 530 await turnResponse.text(), | |
| 531 new RegExp(`"prompt_profile":"${expectedProfile}"`), | |
| 532 ); | |
| 533 }; | |
| 534 | |
| 535 await assertTurnProfile( | |
| 536 userJarC, | |
| 537 userCsrfC2, | |
| 538 'june_admin', | |
| 539 'Admin profile', | |
| 540 ); | |
| 541 | |
| 542 const createMemberR = await authedFetch( | |
| 543 claimBase, | |
| 544 userJarC, | |
| 545 userCsrfC2, | |
| 546 '/api/admin/users', | |
| 547 { | |
| 548 method: 'POST', | |
| 549 headers: { 'Content-Type': 'application/json', Origin: claimBase }, | |
| 550 body: JSON.stringify({ | |
| 551 username: 'invitedfriend', | |
| 552 temporaryPassword: 'InvitedTempPass123!', | |
| 553 role: 'member', | |
| 554 }), | |
| 555 }, | |
| 556 ); | |
| 557 assert.equal(createMemberR.status, 201); | |
| 558 | |
| 559 const memberJar = new CookieJar(); | |
| 560 const memberGuestCsrf = await bootstrapSession(claimBase, memberJar); | |
| 561 const memberLoginR = await authedFetch( | |
| 562 claimBase, | |
| 563 memberJar, | |
| 564 memberGuestCsrf, | |
| 565 '/api/auth/login', | |
| 566 { | |
| 567 method: 'POST', | |
| 568 headers: { 'Content-Type': 'application/json', Origin: claimBase }, | |
| 569 body: JSON.stringify({ | |
| 570 username: 'invitedfriend', | |
| 571 password: 'InvitedTempPass123!', | |
| 572 csrfToken: memberGuestCsrf, | |
| 573 }), | |
| 574 }, | |
| 575 ); | |
| 576 assert.equal(memberLoginR.status, 200); | |
| 577 const memberLoginData = await memberLoginR.json(); | |
| 578 assert.equal(memberLoginData.mustChangePassword, true); | |
| 579 | |
| 580 const memberPasswordCsrf = await bootstrapSession(claimBase, memberJar); | |
| 581 const memberPasswordR = await authedFetch( | |
| 582 claimBase, | |
| 583 memberJar, | |
| 584 memberPasswordCsrf, | |
| 585 '/api/auth/password', | |
| 586 { | |
| 587 method: 'POST', | |
| 588 headers: { 'Content-Type': 'application/json', Origin: claimBase }, | |
| 589 body: JSON.stringify({ | |
| 590 currentPassword: 'InvitedTempPass123!', | |
| 591 newPassword: 'InvitedPermanentPass123!', | |
| 592 csrfToken: memberPasswordCsrf, | |
| 593 }), | |
| 594 }, | |
| 595 ); | |
| 596 assert.equal(memberPasswordR.status, 200); | |
| 597 const memberCsrf = await bootstrapSession(claimBase, memberJar); | |
| 598 await assertTurnProfile( | |
| 599 memberJar, | |
| 600 memberCsrf, | |
| 601 'invited_friend', | |
| 602 'Invited profile', | |
| 603 ); | |
| 500 | 604 |
| 501 // A user cannot claim a conversation owned by a different guest. | 605 // A user cannot claim a conversation owned by a different guest. |
| 502 const claimR = await authedFetch(claimBase, userJarC, userCsrfC2, | 606 const claimR = await authedFetch(claimBase, userJarC, userCsrfC2, |
| 503 '/api/conversations/claim', | 607 '/api/conversations/claim', |
| 504 { | 608 { |