@@ -221,6 +221,11 @@ type SynastryReportApiRecord = {
created_at? : string ;
} ;
type ChatSessionType = "consultation" | "birth_time_rectification" ;
type ChatProfileBinding = {
chartProfileId : string | null ;
chartProfileName : string | null ;
chartProfileRole : "self" | "other" | null ;
} ;
type ChatSession = {
id : string ;
title : string ;
@@ -230,6 +235,9 @@ type ChatSession = {
updatedAt : number ;
sessionType : ChatSessionType ;
rectificationCaseId : string | null ;
chartProfileId : string | null ;
chartProfileName : string | null ;
chartProfileRole : "self" | "other" | null ;
} ;
type RequestError = { sessionId : string ; message : string } ;
@@ -415,6 +423,7 @@ function timestamp() {
function createSession (
modelId : string ,
sessionType : ChatSessionType = "consultation" ,
chartBinding : ChatProfileBinding = { chartProfileId : null , chartProfileName : null , chartProfileRole : null } ,
) : ChatSession {
return {
id : globalThis.crypto.randomUUID ( ) ,
@@ -425,6 +434,7 @@ function createSession(
updatedAt : timestamp ( ) ,
sessionType ,
rectificationCaseId : null ,
. . . chartBinding ,
} ;
}
@@ -513,6 +523,36 @@ function buildSelfChartRecord(profile: Profile): ChartLibraryRecord {
return { id : "self" , role : "self" , profile : { . . . profile , chartRelationship : "self" } , relationship : "self" , updatedAt : timestamp ( ) } ;
}
function chartSnapshotForSession (
chartId : string ,
library : readonly ChartLibraryRecord [ ] ,
fallbackProfile : Profile ,
) : ChatProfileBinding {
const record = library . find ( ( item ) = > item . id === chartId ) ;
if ( record ) {
return {
chartProfileId : record.id ,
chartProfileName : record.profile.name.trim ( ) || ( record . role === "self" ? "我" : "未命名资料" ) ,
chartProfileRole : record.role ,
} ;
}
if ( chartId === "self" ) {
return { chartProfileId : "self" , chartProfileName : fallbackProfile.name.trim ( ) || "我" , chartProfileRole : "self" } ;
}
return { chartProfileId : chartId || null , chartProfileName : "未命名资料" , chartProfileRole : chartId ? "other" : null } ;
}
function sessionChartLabel ( session : ChatSession , library : readonly ChartLibraryRecord [ ] ) {
if ( ! session . chartProfileId ) return "未关联资料" ;
const current = session . chartProfileId === "self" || library . some ( ( record ) = > record . id === session . chartProfileId ) ;
const name = session . chartProfileName ? . trim ( ) || ( session . chartProfileRole === "self" ? "我" : "未命名资料" ) ;
return current ? name : ` 资料已删除 · ${ name } ` ;
}
function sessionSidebarTitle ( session : ChatSession , library : readonly ChartLibraryRecord [ ] ) {
return ` ${ sessionChartLabel ( session , library ) } · ${ session . title || "新对话" } ` ;
}
function upsertSelfChart ( library : ChartLibraryRecord [ ] , profile : Profile ) {
if ( ! profileReadyForLibrary ( profile ) ) return library . filter ( ( record ) = > record . role !== "self" ) ;
const others = library . filter ( ( record ) = > record . role !== "self" ) ;
@@ -843,6 +883,9 @@ function readSessions(value: unknown, catalog: PublicLanguageModelCatalog | null
const session = item as Partial < ChatSession > & {
model_id? : unknown ;
rectification_case_id? : unknown ;
chart_profile_id? : unknown ;
chart_profile_name? : unknown ;
chart_profile_role? : unknown ;
session_type? : unknown ;
updated_at? : unknown ;
} ;
@@ -887,6 +930,11 @@ function readSessions(value: unknown, catalog: PublicLanguageModelCatalog | null
rectificationCaseId : typeof session . rectification_case_id === "string"
? session . rectification_case_id
: null ,
chartProfileId : typeof session . chart_profile_id === "string" ? session.chart_profile_id : null ,
chartProfileName : typeof session . chart_profile_name === "string" ? session.chart_profile_name : null ,
chartProfileRole : session.chart_profile_role === "self" || session . chart_profile_role === "other"
? session . chart_profile_role
: null ,
updatedAt : typeof session . updatedAt === "number"
? session . updatedAt
: typeof session . updated_at === "string"
@@ -1654,6 +1702,9 @@ export default function Home() {
updatedAt : timestamp ( ) ,
sessionType : "consultation" ,
rectificationCaseId : null ,
chartProfileId : "self" ,
chartProfileName : previewProfile.name.trim ( ) || "我" ,
chartProfileRole : "self" ,
} ;
setAccount ( {
user : { id : "preview-user" , email : "preview@local.test" } ,
@@ -1699,11 +1750,16 @@ export default function Home() {
fetchSessions ( controller . signal ) ,
] ) ;
const nextModelCatalog = modelCatalogResult . catalog ;
const nextProfile = readProfile ( nextAccount . profile ) ;
const parsedSessions = readSessions ( sessionsPayload , nextModelCatalog ) ;
let nextSessions = parsedSessions . sessions ;
if ( nextSessions . length === 0 ) {
if ( controller . signal . aborted ) return ;
const initialSession = createSession ( nextModelCatalog ? . defaultModelId ? ? "" ) ;
const initialSession = createSession (
nextModelCatalog ? . defaultModelId ? ? "" ,
"consultation" ,
chartSnapshotForSession ( "self" , [ ] , nextProfile ) ,
) ;
if ( nextModelCatalog ) {
await writeChatSession ( initialSession . id , {
title : initialSession.title ,
@@ -1712,6 +1768,9 @@ export default function Home() {
messages : initialSession.messages ,
session_type : initialSession.sessionType ,
rectification_case_id : initialSession.rectificationCaseId ,
chart_profile_id : initialSession.chartProfileId ,
chart_profile_name : initialSession.chartProfileName ,
chart_profile_role : initialSession.chartProfileRole ,
updated_at : new Date ( initialSession . updatedAt ) . toISOString ( ) ,
} , "create" ) ;
}
@@ -1760,7 +1819,6 @@ export default function Home() {
if ( controller . signal . aborted ) return ;
clearStaleClientReload ( sessionStorage ) ;
const nextProfile = readProfile ( nextAccount . profile ) ;
setAccount ( nextAccount ) ;
setModelCatalog ( nextModelCatalog ) ;
setProfile ( nextProfile ) ;
@@ -2155,6 +2213,9 @@ export default function Home() {
} ) ) ,
session_type : session.sessionType ,
rectification_case_id : session.rectificationCaseId ,
chart_profile_id : session.chartProfileId ,
chart_profile_name : session.chartProfileName ,
chart_profile_role : session.chartProfileRole ,
updated_at : new Date ( session . updatedAt ) . toISOString ( ) ,
} ;
await writeChatSession ( session . id , values , mode ) ;
@@ -2235,7 +2296,11 @@ export default function Home() {
async function startNewChat ( ) : Promise < ChatSession | null > {
if ( ! account || ! modelCatalog || creatingSession ) return null ;
const nextSession = createSession ( modelCatalog . defaultModelId ) ;
const nextSession = createSession (
modelCatalog . defaultModelId ,
"consultation" ,
chartSnapshotForSession ( activeChartId , chartLibrary , profile ) ,
) ;
const previousSessionId = activeSession ? . id ? ? "" ;
setCreatingSession ( true ) ;
setSessions ( ( current ) = > [ nextSession , . . . current ] ) ;
@@ -2273,6 +2338,13 @@ export default function Home() {
setDraft ( "" ) ;
setDraftEntrypoint ( null ) ;
setComposerNotice ( "" ) ;
if ( nextSession ? . chartProfileId ) {
const boundChart = chartLibrary . find ( ( record ) = > record . id === nextSession . chartProfileId ) ;
if ( boundChart && boundChart . id !== activeChartId && accountId ) {
setActiveChartId ( boundChart . id ) ;
localStorage . setItem ( activeChartStorageKey ( accountId ) , boundChart . id ) ;
}
}
if ( nextSession ? . sessionType === "birth_time_rectification" ) {
setRectificationError ( "" ) ;
if ( nextSession . id !== rectificationSessionId ) {
@@ -2830,6 +2902,7 @@ export default function Home() {
updatedAt : timestamp ( ) ,
sessionType : "birth_time_rectification" ,
rectificationCaseId : opened.caseId ,
. . . chartSnapshotForSession ( activeChartId , chartLibrary , profile ) ,
} ;
setSessions ( ( current ) = > [ merged , . . . current . filter ( ( session ) = > session . id !== merged . id ) ] ) ;
void persistSession ( merged ) . catch ( ( ) = > { } ) ;
@@ -3859,7 +3932,7 @@ export default function Home() {
const sidebarSessions = visibleSessions . map ( ( session ) = > ( {
id : session.id ,
title : session.title ,
title : sessionSidebarTitle ( session , chartLibrary ) ,
pinned : pinnedSessionIds.includes ( session . id ) ,
archived : archivedSessionIds.includes ( session . id ) ,
} ) ) ;
@@ -4150,6 +4223,7 @@ export default function Home() {
< SidebarTrigger placement = "inset" / >
< div >
< strong > { activeSession ? . title || "新对话" } < / strong >
< span className = "chat-header-subtitle" > 分 析 对 象 : { activeSession ? sessionChartLabel ( activeSession , chartLibrary ) : "未关联资料" } < / span >
< / div >
< div className = "chat-header-actions" >
< div className = "chat-header-rectification" data-rectification-header-slot = "" ref = { setRectificationHeaderSlot } / >