From 1ab36cc7947de984e5df6c97fddcfff764a98f7c Mon Sep 17 00:00:00 2001 From: conrad mugabe Date: Tue, 14 Jul 2026 00:19:33 +0200 Subject: [PATCH 1/3] style: normalize prettier formatting drift on main The pre-commit hook runs `prettier --write .` across the whole repo and `git add -u`, so pre-existing formatting drift on main (CHANGELOG bullet style, a missing trailing newline in an e2e spec) would otherwise be swept into an unrelated fix commit. Isolate it here so the fix and test commits stay focused. Co-Authored-By: Claude Opus 4.8 (1M context) --- CHANGELOG.md | 42 +++++++++---------- .../14-anonymous-public-access.spec.ts | 2 +- 2 files changed, 22 insertions(+), 22 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index eae69ab8..1a7a641b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,51 +4,51 @@ ### Bug Fixes -* **e2e-test:** fix for the e2e tests for tasks ([2050cb7](https://github.com/iblai/os/commit/2050cb71578a7d4d771431c59a3ff9f46db78cb5)) -* **e2e-test:** more fixes for the e2e tests ([3655577](https://github.com/iblai/os/commit/365557761457aa4a0790b6e5cb3e007b7a40da50)) -* **e2e-tests:** adding fixes for lti tests ([07e9ee1](https://github.com/iblai/os/commit/07e9ee1f77e81aaecc4a6b2315f805a04001a2f7)) -* **e2e-tests:** fixing e2e tests for lti ([b9cc7d7](https://github.com/iblai/os/commit/b9cc7d79d54278b7b754dd641a63cd4a698de6be)) -* **e2e-tests:** fixing e2e tests for task tab and sdk version bump ([681657a](https://github.com/iblai/os/commit/681657a7d8af2e81fb5b979ab6e4eeedff5f45ad)) -* **e2e-tests:** fixing playwright tests for lti ([e6e28b1](https://github.com/iblai/os/commit/e6e28b1db8295cee7e9ab9c1e10aa58f1342037d)) -* **e2e-tests:** fixing test cover for journey 56 to 57 ([0aea5ad](https://github.com/iblai/os/commit/0aea5ad37fcfa90b9160accbc5c699c8cfba3689)) -* **e2e-tests:** journey updates for tests coverage ([34613af](https://github.com/iblai/os/commit/34613af2f311e133d8a7d7afffae848ad5ce4b90)) -* **mentor:** fixing tests for jounery 14 ([09bd905](https://github.com/iblai/os/commit/09bd90556082b234a39db88ab5719a509900502a)) -* **mentor:** fixing tests for jounery 14 ([d8df25e](https://github.com/iblai/os/commit/d8df25ed7f8df7c9aa6169582c828b13b4d72ac2)) -* **mentor:** translation for lti, e2e test and checkpoints fixes ([ffe6993](https://github.com/iblai/os/commit/ffe6993e536b0ffc85855ec4aab3585e92576c0c)) +- **e2e-test:** fix for the e2e tests for tasks ([2050cb7](https://github.com/iblai/os/commit/2050cb71578a7d4d771431c59a3ff9f46db78cb5)) +- **e2e-test:** more fixes for the e2e tests ([3655577](https://github.com/iblai/os/commit/365557761457aa4a0790b6e5cb3e007b7a40da50)) +- **e2e-tests:** adding fixes for lti tests ([07e9ee1](https://github.com/iblai/os/commit/07e9ee1f77e81aaecc4a6b2315f805a04001a2f7)) +- **e2e-tests:** fixing e2e tests for lti ([b9cc7d7](https://github.com/iblai/os/commit/b9cc7d79d54278b7b754dd641a63cd4a698de6be)) +- **e2e-tests:** fixing e2e tests for task tab and sdk version bump ([681657a](https://github.com/iblai/os/commit/681657a7d8af2e81fb5b979ab6e4eeedff5f45ad)) +- **e2e-tests:** fixing playwright tests for lti ([e6e28b1](https://github.com/iblai/os/commit/e6e28b1db8295cee7e9ab9c1e10aa58f1342037d)) +- **e2e-tests:** fixing test cover for journey 56 to 57 ([0aea5ad](https://github.com/iblai/os/commit/0aea5ad37fcfa90b9160accbc5c699c8cfba3689)) +- **e2e-tests:** journey updates for tests coverage ([34613af](https://github.com/iblai/os/commit/34613af2f311e133d8a7d7afffae848ad5ce4b90)) +- **mentor:** fixing tests for jounery 14 ([09bd905](https://github.com/iblai/os/commit/09bd90556082b234a39db88ab5719a509900502a)) +- **mentor:** fixing tests for jounery 14 ([d8df25e](https://github.com/iblai/os/commit/d8df25ed7f8df7c9aa6169582c828b13b4d72ac2)) +- **mentor:** translation for lti, e2e test and checkpoints fixes ([ffe6993](https://github.com/iblai/os/commit/ffe6993e536b0ffc85855ec4aab3585e92576c0c)) ## [0.88.4](https://github.com/iblai/os/compare/v0.93.1...v0.94.0) (2026-07-01) ### Features -* **e2e-tests:** adding e2e tests for lti ([97d6e4e](https://github.com/iblai/os/commit/97d6e4ee30a2bb03616bfa984f094d49ef347f06)) +- **e2e-tests:** adding e2e tests for lti ([97d6e4e](https://github.com/iblai/os/commit/97d6e4ee30a2bb03616bfa984f094d49ef347f06)) ### Bug Fixes -* **e2e-tests:** fixing journey 20 for the nested dialouge multiple elements ([c0eb757](https://github.com/iblai/os/commit/c0eb7570b6f511cc6e8c6e56b4637154bd49ede8)) -* **mentorai:** version bump for iblai-js ([549dd1d](https://github.com/iblai/os/commit/549dd1dcaeb7fd4f9ec6f7c9a56d982045abcf38)) +- **e2e-tests:** fixing journey 20 for the nested dialouge multiple elements ([c0eb757](https://github.com/iblai/os/commit/c0eb7570b6f511cc6e8c6e56b4637154bd49ede8)) +- **mentorai:** version bump for iblai-js ([549dd1d](https://github.com/iblai/os/commit/549dd1dcaeb7fd4f9ec6f7c9a56d982045abcf38)) ## [0.93.1](https://github.com/iblai/os/compare/v0.93.0...v0.93.1) (2026-07-08) ### Bug Fixes -* **chat:** preserve LaTeX delimiters in preprocessLaTeX currency escape ([7502422](https://github.com/iblai/os/commit/75024224f69060780e3646ea40375fe891c2ebb7)) +- **chat:** preserve LaTeX delimiters in preprocessLaTeX currency escape ([7502422](https://github.com/iblai/os/commit/75024224f69060780e3646ea40375fe891c2ebb7)) ### Chores -* normalize CHANGELOG formatting via prettier ([f60d24b](https://github.com/iblai/os/commit/f60d24bd81b32e88f65fa1ecc11de218cf279f91)) +- normalize CHANGELOG formatting via prettier ([f60d24b](https://github.com/iblai/os/commit/f60d24bd81b32e88f65fa1ecc11de218cf279f91)) ### Tests -* **chat:** cover LaTeX delimiter preservation and KaTeX rendering ([3a01172](https://github.com/iblai/os/commit/3a01172acfb5762d6b03f7edca93f70e8dfc4fc2)) +- **chat:** cover LaTeX delimiter preservation and KaTeX rendering ([3a01172](https://github.com/iblai/os/commit/3a01172acfb5762d6b03f7edca93f70e8dfc4fc2)) ## [0.93.0](https://github.com/iblai/os/compare/v0.92.4...v0.93.0) (2026-07-08) ### Features -* ecommerce playwright full flow coverage with credit cleanup ([ceb5612](https://github.com/iblai/os/commit/ceb56121d056f34faab247af93c612b4aac41a9e)) -* ecommerce playwright full flow coverage with credit cleanup ([b463105](https://github.com/iblai/os/commit/b463105a33b7e5c6cddec87801367f7459e157fa)) -* ecommerce playwright full flow coverage with credit cleanup ([d7d3e67](https://github.com/iblai/os/commit/d7d3e6726d5768d749c685c2a721145ea4a72caa)) -* ecommerce playwright full flow coverage with credit cleanup > misleanding env example fixed ([de30e48](https://github.com/iblai/os/commit/de30e484bcfb78268a7cdf1119552026c20aab07)) +- ecommerce playwright full flow coverage with credit cleanup ([ceb5612](https://github.com/iblai/os/commit/ceb56121d056f34faab247af93c612b4aac41a9e)) +- ecommerce playwright full flow coverage with credit cleanup ([b463105](https://github.com/iblai/os/commit/b463105a33b7e5c6cddec87801367f7459e157fa)) +- ecommerce playwright full flow coverage with credit cleanup ([d7d3e67](https://github.com/iblai/os/commit/d7d3e6726d5768d749c685c2a721145ea4a72caa)) +- ecommerce playwright full flow coverage with credit cleanup > misleanding env example fixed ([de30e48](https://github.com/iblai/os/commit/de30e484bcfb78268a7cdf1119552026c20aab07)) ## [0.92.4](https://github.com/iblai/os/compare/v0.92.3...v0.92.4) (2026-07-08) diff --git a/e2e/journeys/14-anonymous-public-access.spec.ts b/e2e/journeys/14-anonymous-public-access.spec.ts index 70657345..a7a0165d 100644 --- a/e2e/journeys/14-anonymous-public-access.spec.ts +++ b/e2e/journeys/14-anonymous-public-access.spec.ts @@ -271,4 +271,4 @@ test.describe('Journey 14: Anonymous / Public Access', () => { true, ); }); -}); \ No newline at end of file +}); From 4643817d7479a014183570931939925ea6b6673a Mon Sep 17 00:00:00 2001 From: conrad mugabe Date: Tue, 14 Jul 2026 00:22:14 +0200 Subject: [PATCH 2/3] fix(mentor): guard guided-prompts user id in embed mode In embed mode the current username arrives as an empty string before hydration, and the proactive-greeting EOS handler fired the lazy guided-prompts trigger with it verbatim. That produced a malformed URL with an empty path segment (/users//sessions/) and a 404. Fall back to 'anonymous' when username is falsy, matching the other guided-prompts call sites, so the path segment is always valid. Co-Authored-By: Claude Opus 4.8 (1M context) --- hooks/use-welcome-message.ts | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/hooks/use-welcome-message.ts b/hooks/use-welcome-message.ts index 48a54bab..7ed26bbc 100644 --- a/hooks/use-welcome-message.ts +++ b/hooks/use-welcome-message.ts @@ -77,11 +77,12 @@ export default function useWelcome({ if (response?.eos) { setTimeout(() => { _endConnection(); + const guidedUserId = username || 'anonymous'; loadGuidedPrompts({ org: tenantKey, sessionId, - // @ts-ignore - userId: username, + // @ts-ignore - userId is a valid runtime path param not yet in the query arg type + userId: guidedUserId, }); }, 200); } From aad4f6cf0837705cb88731ab9dcadf0d961c49b1 Mon Sep 17 00:00:00 2001 From: conrad mugabe Date: Tue, 14 Jul 2026 00:24:43 +0200 Subject: [PATCH 3/3] test(mentor): cover empty username fallback for guided prompts Assert the proactive-greeting EOS handler dispatches guided-prompts with userId 'anonymous' when the username is an empty string (embed mode), and passes a real username through unchanged. Guards against regressing the malformed /users//sessions/ URL. Co-Authored-By: Claude Opus 4.8 (1M context) --- hooks/__tests__/use-welcome-message.test.ts | 95 ++++++++++++++++++++- 1 file changed, 94 insertions(+), 1 deletion(-) diff --git a/hooks/__tests__/use-welcome-message.test.ts b/hooks/__tests__/use-welcome-message.test.ts index 468802c3..74ed5f16 100644 --- a/hooks/__tests__/use-welcome-message.test.ts +++ b/hooks/__tests__/use-welcome-message.test.ts @@ -131,6 +131,14 @@ describe('useWelcome', () => { expect(MockWebSocketConstructor).toHaveBeenCalledWith('wss://test-url'); }); + it('should default isNewSession to true and create WebSocket when omitted', () => { + const { isNewSession, ...propsWithoutIsNewSession } = defaultProps; + + renderHook(() => useWelcome(propsWithoutIsNewSession)); + + expect(MockWebSocketConstructor).toHaveBeenCalledWith('wss://test-url'); + }); + it('should not create WebSocket when isNewSession is false', () => { renderHook(() => useWelcome({ @@ -404,7 +412,7 @@ describe('useWelcome', () => { 'Normal closure', ); - // Should have loaded guided prompts + // Should have loaded guided prompts with the real username passed through expect(mockLoadGuidedPrompts).toHaveBeenCalledWith({ org: 'tenant-1', sessionId: 'session-123', @@ -414,6 +422,91 @@ describe('useWelcome', () => { vi.useRealTimers(); }); + it('should pass through a real username to guided prompts on eos (issue #2148)', async () => { + vi.useFakeTimers(); + + mockUseMentorSettings.mockReturnValue({ + data: { + greetingMethod: 'proactive_prompt', + proactiveResponse: null, + }, + }); + + mockWebSocketInstance.readyState = WebSocket.OPEN; + + renderHook(() => + useWelcome({ + ...defaultProps, + username: 'jdoe', + }), + ); + + act(() => { + mockWebSocketInstance.onmessage?.( + new MessageEvent('message', { + data: JSON.stringify({ eos: true }), + }), + ); + }); + + await act(async () => { + vi.advanceTimersByTime(200); + }); + + expect(mockLoadGuidedPrompts).toHaveBeenCalledWith({ + org: 'tenant-1', + sessionId: 'session-123', + userId: 'jdoe', + }); + + vi.useRealTimers(); + }); + + it('should fall back to "anonymous" when username is empty in embed mode on eos (issue #2148)', async () => { + vi.useFakeTimers(); + + mockUseMentorSettings.mockReturnValue({ + data: { + greetingMethod: 'proactive_prompt', + proactiveResponse: null, + }, + }); + + mockWebSocketInstance.readyState = WebSocket.OPEN; + + // Embed mode passes username as an empty string before hydration. + renderHook(() => + useWelcome({ + ...defaultProps, + username: '', + }), + ); + + act(() => { + mockWebSocketInstance.onmessage?.( + new MessageEvent('message', { + data: JSON.stringify({ eos: true }), + }), + ); + }); + + await act(async () => { + vi.advanceTimersByTime(200); + }); + + // Must never send an empty userId (would produce /users//sessions/ -> 404). + expect(mockLoadGuidedPrompts).toHaveBeenCalledWith({ + org: 'tenant-1', + sessionId: 'session-123', + userId: 'anonymous', + }); + expect(mockLoadGuidedPrompts).not.toHaveBeenCalledWith( + expect.objectContaining({ userId: '' }), + ); + + vi.useRealTimers(); + }); + it('should close WebSocket with explicit code 1000 on unmount cleanup', () => { mockUseMentorSettings.mockReturnValue({ data: {