Merge branch 'cross-thread-memory-profiles' into episodic-memory-sdk

This commit is contained in:
Robin Braumann 2026-05-12 08:06:20 +02:00
commit 8fff55d7bc
2 changed files with 51 additions and 8 deletions

View File

@ -310,4 +310,41 @@ describe('AgentMemoryPanel', () => {
'Profile for the second agent.',
);
});
it('does not start a duplicate profile request when switching back to an in-flight agent id', async () => {
const firstLoad = deferred<{ userProfile: string | null }>();
const secondLoad = deferred<{ userProfile: string | null }>();
getAgentMemoryProfilesMock
.mockReturnValueOnce(firstLoad.promise)
.mockReturnValueOnce(secondLoad.promise);
const wrapper = mountPanel();
await wrapper.find('[data-testid="agent-memory-profiles-toggle"]').trigger('click');
await wrapper.setProps({ agentId: 'agent-2' });
await wrapper.setProps({ agentId: 'agent-1' });
expect(getAgentMemoryProfilesMock).toHaveBeenCalledTimes(2);
expect(getAgentMemoryProfilesMock).toHaveBeenNthCalledWith(
1,
restApiContext,
'project-1',
'agent-1',
);
expect(getAgentMemoryProfilesMock).toHaveBeenNthCalledWith(
2,
restApiContext,
'project-1',
'agent-2',
);
secondLoad.resolve({ userProfile: 'Stale second profile.' });
await flushPromises();
expect(wrapper.text()).toContain('Loading user profile...');
firstLoad.resolve({ userProfile: 'Profile for the first agent.' });
await flushPromises();
expect(wrapper.find('[data-testid="agent-memory-user-profile"]').text()).toContain(
'Profile for the first agent.',
);
});
});

View File

@ -30,11 +30,13 @@ const profilesKey = computed(() =>
);
const profilesExpanded = ref(false);
const loadedProfilesKey = ref<string | null>(null);
const loadingProfilesKey = ref<string | null>(null);
const loadingProfilesKeys = ref(new Set<string>());
const profilesError = ref(false);
const profiles = ref<AgentMemoryProfilesResponse | null>(null);
const profilesLoaded = computed(() => loadedProfilesKey.value === profilesKey.value);
const profilesLoading = computed(() => loadingProfilesKey.value === profilesKey.value);
const profilesLoading = computed(
() => profilesKey.value !== null && loadingProfilesKeys.value.has(profilesKey.value),
);
function onEnableMemory() {
const existingMemory = props.config?.memory;
@ -64,17 +66,19 @@ function onMemoryToggle(enabled: boolean) {
async function loadProfiles() {
const key = profilesKey.value;
if (!canLoadProfiles.value || !props.projectId || !props.agentId || !key) return;
if (loadingProfilesKey.value === key) return;
const projectId = props.projectId;
const agentId = props.agentId;
if (!canLoadProfiles.value || !projectId || !agentId || !key) return;
if (loadingProfilesKeys.value.has(key)) return;
loadingProfilesKey.value = key;
loadingProfilesKeys.value = new Set([...loadingProfilesKeys.value, key]);
profilesError.value = false;
try {
const loadedProfiles = await getAgentMemoryProfiles(
rootStore.restApiContext,
props.projectId,
props.agentId,
projectId,
agentId,
);
if (profilesKey.value !== key) return;
profiles.value = loadedProfiles;
@ -83,7 +87,9 @@ async function loadProfiles() {
if (profilesKey.value !== key) return;
profilesError.value = true;
} finally {
if (loadingProfilesKey.value === key) loadingProfilesKey.value = null;
const nextLoadingKeys = new Set(loadingProfilesKeys.value);
nextLoadingKeys.delete(key);
loadingProfilesKeys.value = nextLoadingKeys;
}
}