@@ -16,6 +16,13 @@ import {
1616 type DashboardAgentSession ,
1717} from "./DashboardAgentChat" ;
1818import { createCoalescedReload } from "./coalesced-reload" ;
19+ import {
20+ forgetLastChat ,
21+ lastChatStorageKey ,
22+ readLastChat ,
23+ shouldPersistLastChat ,
24+ writeLastChat ,
25+ } from "./last-chat-storage" ;
1926import { DashboardAgentDraft } from "./DashboardAgentDraft" ;
2027import type { TurnActivity } from "./DashboardAgentMessages" ;
2128import { DashboardAgentHeader } from "./DashboardAgentHeader" ;
@@ -27,23 +34,6 @@ import { agentPageLabel } from "./page-label";
2734import { AgentPanelColumn } from "./panel-layout" ;
2835import { concurrencyPath } from "~/utils/pathBuilder" ;
2936
30- const lastChatStorageKey = ( organizationId : string ) =>
31- `tdev:dashboard-agent:last-chat:${ organizationId } ` ;
32-
33- function readLastChat ( storageKey : string ) : { chatId : string ; path : string } | null {
34- if ( typeof window === "undefined" ) return null ;
35- try {
36- const raw = window . localStorage . getItem ( storageKey ) ;
37- if ( ! raw ) return null ;
38- // Pre-path entries were the bare chat id: no page to match, so start fresh.
39- if ( ! raw . startsWith ( "{" ) ) return null ;
40- const parsed = JSON . parse ( raw ) as { chatId ?: string ; path ?: string } ;
41- return parsed . chatId && parsed . path ? { chatId : parsed . chatId , path : parsed . path } : null ;
42- } catch {
43- return null ;
44- }
45- }
46-
4737function serializePageContext ( pageContext : AgentPageContext ) : string | undefined {
4838 try {
4939 return JSON . stringify ( pageContext ) ;
@@ -54,6 +44,8 @@ function serializePageContext(pageContext: AgentPageContext): string | undefined
5444
5545type ActiveChat = {
5646 chatId : string ;
47+ // The org the chat belongs to, so a switch can't file it under the new org's key.
48+ organizationId : string ;
5749 messages : UIMessage [ ] ;
5850 session : DashboardAgentSession | null ;
5951 pendingFirstMessage ?: string ;
@@ -158,7 +150,13 @@ export function DashboardAgentPanel({
158150 const data = res . ok ? ( ( await res . json ( ) ) as OpenedChatResponse ) : undefined ;
159151 if ( seq !== openChatRequestSeq . current ) return ;
160152 const opened = resolveOpenedChat ( id , data ) ;
161- setActive ( opened . kind === "gone" ? null : opened ) ;
153+ if ( opened . kind === "gone" ) {
154+ // Deleted, or another org's: drop the pointer so it can't be restored again.
155+ setActive ( null ) ;
156+ forgetLastChat ( storageKey ) ;
157+ return ;
158+ }
159+ setActive ( { ...opened , organizationId : organization . id } ) ;
162160 } catch ( error ) {
163161 console . error ( `Dashboard agent: failed to open chat ${ id } ` , error ) ;
164162 toast . error ( "We couldn't open that chat. Try again in a moment." ) ;
@@ -167,7 +165,7 @@ export function DashboardAgentPanel({
167165 if ( seq === openChatRequestSeq . current ) setLoading ( false ) ;
168166 }
169167 } ,
170- [ actionPath , toast ]
168+ [ actionPath , organization . id , storageKey , toast ]
171169 ) ;
172170
173171 const createChat = useCallback (
@@ -200,6 +198,7 @@ export function DashboardAgentPanel({
200198 }
201199 setActive ( {
202200 chatId : data . chatId ,
201+ organizationId : organization . id ,
203202 messages : data . headStarted ? [ userMessage ] : [ ] ,
204203 session : { publicAccessToken : data . publicAccessToken } ,
205204 pendingFirstMessage : data . headStarted ? undefined : text ,
@@ -213,7 +212,7 @@ export function DashboardAgentPanel({
213212 if ( seq === openChatRequestSeq . current ) setLoading ( false ) ;
214213 }
215214 } ,
216- [ actionPath , clientData , toast ]
215+ [ actionPath , clientData , organization . id , toast ]
217216 ) ;
218217
219218 const restored = useRef ( false ) ;
@@ -244,16 +243,9 @@ export function DashboardAgentPanel({
244243 } , [ organization . id , loadHistory ] ) ;
245244
246245 useEffect ( ( ) => {
247- if ( ! active ?. chatId ) return ;
248- try {
249- window . localStorage . setItem (
250- storageKey ,
251- JSON . stringify ( { chatId : active . chatId , path : location . pathname } )
252- ) ;
253- } catch {
254- /* ignore */
255- }
256- } , [ active ?. chatId , storageKey , location . pathname ] ) ;
246+ if ( ! shouldPersistLastChat ( active , organization . id ) ) return ;
247+ writeLastChat ( storageKey , { chatId : active . chatId , path : location . pathname } ) ;
248+ } , [ active , organization . id , storageKey , location . pathname ] ) ;
257249
258250 // Bound to its chat, which remounts with a fresh guard ref on every switch.
259251 const [ prefill , setPrefill ] = useState < { text : string ; seq : number ; chatId : string } | undefined > (
0 commit comments