fix(hololake): avoid no-op agent workspace writes
This commit is contained in:
parent
392d205341
commit
dc1a32a52b
6 changed files with 72 additions and 5 deletions
|
|
@ -360,6 +360,30 @@ describe('AiWorkspace', () => {
|
|||
expect(screen.queryByRole('button', { name: 'Current work' })).toBeNull()
|
||||
})
|
||||
|
||||
it('does not rewrite unchanged conversation settings when the workspace opens', async () => {
|
||||
const onConversationSettingsChange = vi.fn()
|
||||
|
||||
render(
|
||||
<AiWorkspace
|
||||
open
|
||||
mode="side"
|
||||
aiAgentsStatus={installedStatuses()}
|
||||
aiModelProviders={providers}
|
||||
conversationSettings={[
|
||||
{ id: 'live-chat', title: 'Current work', target_id: null, archived: false },
|
||||
]}
|
||||
vaultPath="/tmp/vault"
|
||||
onClose={vi.fn()}
|
||||
onConversationSettingsChange={onConversationSettingsChange}
|
||||
/>,
|
||||
)
|
||||
|
||||
await waitFor(() => {
|
||||
expect(screen.getByRole('button', { name: 'Current work' })).toBeTruthy()
|
||||
})
|
||||
expect(onConversationSettingsChange).not.toHaveBeenCalled()
|
||||
})
|
||||
|
||||
it('recovers stored sessions that no longer have conversation metadata', async () => {
|
||||
setAiWorkspaceSessionMessages('orphaned-chat', [{
|
||||
userMessage: 'Recovered prompt',
|
||||
|
|
|
|||
|
|
@ -197,6 +197,20 @@ function conversationsToSettings(conversations: AiConversation[]): AiWorkspaceCo
|
|||
}))
|
||||
}
|
||||
|
||||
function conversationSettingsEqual(
|
||||
current: AiWorkspaceConversationSetting[],
|
||||
stored: AiWorkspaceConversationSetting[] | null | undefined,
|
||||
): boolean {
|
||||
if (!stored || current.length !== stored.length) return false
|
||||
return current.every((conversation, index) => {
|
||||
const persisted = stored[index]
|
||||
return conversation.archived === (persisted.archived === true)
|
||||
&& conversation.id === persisted.id
|
||||
&& conversation.target_id === (persisted.target_id?.trim() || null)
|
||||
&& conversation.title === persisted.title
|
||||
})
|
||||
}
|
||||
|
||||
export function activeConversationForState(
|
||||
conversations: AiConversation[],
|
||||
activeId: ConversationId,
|
||||
|
|
@ -370,10 +384,12 @@ function initialActiveId(conversations: AiConversation[], requestedId: Conversat
|
|||
function useConversationSettingsPersistence({
|
||||
conversations,
|
||||
onSettingsChange,
|
||||
settings,
|
||||
settingsReady,
|
||||
}: {
|
||||
conversations: AiConversation[]
|
||||
onSettingsChange?: (conversations: AiWorkspaceConversationSetting[]) => void
|
||||
settings?: AiWorkspaceConversationSetting[] | null
|
||||
settingsReady: boolean
|
||||
}) {
|
||||
const onSettingsChangeRef = useRef(onSettingsChange)
|
||||
|
|
@ -384,8 +400,10 @@ function useConversationSettingsPersistence({
|
|||
|
||||
useEffect(() => {
|
||||
if (!settingsReady) return
|
||||
onSettingsChangeRef.current?.(conversationsToSettings(conversations))
|
||||
}, [conversations, settingsReady])
|
||||
const nextSettings = conversationsToSettings(conversations)
|
||||
if (conversationSettingsEqual(nextSettings, settings)) return
|
||||
onSettingsChangeRef.current?.(nextSettings)
|
||||
}, [conversations, settings, settingsReady])
|
||||
}
|
||||
|
||||
function useTitleConversationFromAnswer(setConversations: SetConversations) {
|
||||
|
|
@ -490,7 +508,7 @@ export function useConversations({
|
|||
|
||||
const titleConversationFromAnswer = useTitleConversationFromAnswer(setConversations)
|
||||
const updateDefaultConversationTargets = useUpdateDefaultConversationTargets(setConversations)
|
||||
useConversationSettingsPersistence({ conversations, onSettingsChange, settingsReady })
|
||||
useConversationSettingsPersistence({ conversations, onSettingsChange, settings, settingsReady })
|
||||
|
||||
return {
|
||||
activeId, addConversation, archiveConversation, closeConversation, conversations, deleteConversation, forkConversation,
|
||||
|
|
|
|||
Loading…
Reference in a new issue