Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
43 changes: 24 additions & 19 deletions frontend/src/stores/account-auth.js
Original file line number Diff line number Diff line change
Expand Up @@ -162,6 +162,10 @@ export const useAccountAuthStore = defineStore('account-auth', {
}
}

useProductExpertSupportAgentStore().$reset()
useProductExpertInsightsAgentStore().$reset()
useProductExpertStore().$reset()

if (router.currentRoute.value.meta.requiresLogin !== false) {
const currentPath = router.currentRoute.value.fullPath === '/'
? window.location.pathname + window.location.search + window.location.hash
Expand Down Expand Up @@ -207,32 +211,33 @@ export const useAccountAuthStore = defineStore('account-auth', {
)
return disconnect
.then(() => userApi.logout())
.then(() => {
useAccountAuthStore().$reset()
useAccountStore().$reset()
useUxLoadingStore().$reset()
useAccountSettingsStore().$reset()
useUxDialogStore().$reset()
useUxToursStore().$reset()
useUxNavigationStore().$reset()
useUxDrawersStore().$reset()
useUxStore().$reset()
useContextStore().$reset()
useCookieConsentStore().reset()
useProductTablesStore().$reset()
useProductBrokersStore().$reset()
useProductAssistantStore().$reset()
useProductExpertSupportAgentStore().$reset()
useProductExpertInsightsAgentStore().$reset()
useProductExpertStore().$reset()
})
.then(() => this.clearStores())
.catch(_ => {})
.finally(() => {
if (window._hsq) {
window._hsq.push(['revokeCookieConsent'])
}
window.location = logoutURL
})
},
clearStores () {
useAccountAuthStore().$reset()
useAccountStore().$reset()
useUxLoadingStore().$reset()
useAccountSettingsStore().$reset()
useUxDialogStore().$reset()
useUxToursStore().$reset()
useUxNavigationStore().$reset()
useUxDrawersStore().$reset()
useUxStore().$reset()
useContextStore().$reset()
useCookieConsentStore().reset()
useProductTablesStore().$reset()
useProductBrokersStore().$reset()
useProductAssistantStore().$reset()
useProductExpertSupportAgentStore().$reset()
useProductExpertInsightsAgentStore().$reset()
useProductExpertStore().$reset()
}
},
persist: {
Expand Down
12 changes: 12 additions & 0 deletions frontend/src/stores/product-expert-insights-agent.js
Original file line number Diff line number Diff line change
Expand Up @@ -46,5 +46,17 @@ export const useProductExpertInsightsAgentStore = defineStore('product-expert-in
const data = await expertApi.getCapabilities({ context: { teamId: team.id } })
this.capabilityServers = data.servers || []
}
},
persist: {
pick: ['messages', 'sessionId', 'sessionStartTime', 'sessionWarningShown', 'sessionExpiredShown', 'selectedCapabilities'],
storage: localStorage,
afterHydrate (store) {
store.messages.forEach(msg => {
msg._streamed = true
if (msg.answer) {
msg.answer.forEach(a => { a._streamed = true })
}
})
}
}
})
12 changes: 10 additions & 2 deletions frontend/src/stores/product-expert-support-agent.js
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,15 @@ export const useProductExpertSupportAgentStore = defineStore('product-expert-sup
}
},
persist: {
pick: ['context'],
storage: localStorage
pick: ['context', 'messages', 'sessionId', 'sessionStartTime', 'sessionWarningShown', 'sessionExpiredShown'],
storage: localStorage,
afterHydrate (store) {
store.messages.forEach(msg => {
msg._streamed = true
if (msg.answer) {
msg.answer.forEach(a => { a._streamed = true })
}
})
}
}
})
43 changes: 26 additions & 17 deletions frontend/src/stores/product-expert.js
Original file line number Diff line number Diff line change
Expand Up @@ -144,6 +144,9 @@ export const useProductExpertStore = defineStore('product-expert', {
this.setAgentMode(INSIGHTS_AGENT)
}

// Resume the session check interval if a persisted session exists (e.g. after page refresh)
this.resumeSessionTimer()

// In immersive editor context, navigate to the Expert tab instead of opening RightDrawer
const contextStore = useContextStore()
if (contextStore.isImmersiveEditor) {
Expand Down Expand Up @@ -664,26 +667,13 @@ export const useProductExpertStore = defineStore('product-expert', {
}
},
// Session timing actions
startSessionTimer () {
_startSessionCheckInterval () {
const agentStore = this._agentStore

// Clear any existing timer
if (agentStore.sessionCheckTimer) {
clearInterval(agentStore.sessionCheckTimer)
}

// Set session start time
agentStore.sessionStartTime = Date.now()
agentStore.sessionWarningShown = false
agentStore.sessionExpiredShown = false

// Check every 30 seconds if we've reached the warning/expiration threshold
const timer = setInterval(() => {
const elapsed = Date.now() - agentStore.sessionStartTime
const warningThreshold = 25 * 60 * 1000 // 25 minutes
const expirationThreshold = 28 * 60 * 1000 // 28 minutes

// Show 25-minute warning
if (elapsed >= warningThreshold && !agentStore.sessionWarningShown) {
agentStore.sessionWarningShown = true
this.addSystemMessage({
Expand All @@ -692,18 +682,30 @@ export const useProductExpertStore = defineStore('product-expert', {
})
}

// Show 30-minute expiration
if (elapsed >= expirationThreshold && !agentStore.sessionExpiredShown) {
agentStore.sessionExpiredShown = true
this.addSystemMessage({
message: 'Your conversation history has expired. Chat is now disabled. Click "Start Over" to begin a new conversation.',
type: 'expired'
})
}
}, 30000) // Check every 30 seconds
}, 30000)

agentStore.setSessionCheckTimer(timer)
},
startSessionTimer () {
const agentStore = this._agentStore

if (agentStore.sessionCheckTimer) {
clearInterval(agentStore.sessionCheckTimer)
}

agentStore.sessionStartTime = Date.now()
agentStore.sessionWarningShown = false
agentStore.sessionExpiredShown = false

this._startSessionCheckInterval()
},
resetSessionTimer () {
const agentStore = this._agentStore
if (agentStore.sessionCheckTimer) {
Expand All @@ -714,6 +716,13 @@ export const useProductExpertStore = defineStore('product-expert', {
agentStore.sessionWarningShown = false
agentStore.sessionExpiredShown = false
},
// Restart the session check interval without resetting sessionStartTime.
// Used after page refresh to let the persisted timer continue its course.
resumeSessionTimer () {
const agentStore = this._agentStore
if (!agentStore.sessionStartTime || agentStore.sessionCheckTimer) return
this._startSessionCheckInterval()
},
/**
*
* @param {'support-agent' | 'insights-agent'} mode
Expand Down Expand Up @@ -1300,7 +1309,7 @@ export const useProductExpertStore = defineStore('product-expert', {
}
},
persist: {
pick: ['shouldWakeUpAssistant', 'questionCadence'],
pick: ['shouldWakeUpAssistant', 'questionCadence', 'agentMode'],
storage: localStorage
}
})
Loading