mirror of
https://github.com/n8n-io/n8n.git
synced 2026-10-19 16:55:02 +02:00
fix(editor): Fix blank workflow previews in AI Assistant (backport to release-candidate/2.40.x) (#38914)
Co-authored-by: Romeo Balta <7095569+romeobalta@users.noreply.github.com> Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
parent
a8e0e7c384
commit
2049d15dbe
|
|
@ -1,4 +1,5 @@
|
|||
import { setActivePinia, createPinia } from 'pinia';
|
||||
import { effectScope, nextTick } from 'vue';
|
||||
import { beforeAll, afterAll, beforeEach, describe, expect, it, vi } from 'vitest';
|
||||
import { ensureThread } from '../instanceAi.api';
|
||||
import {
|
||||
|
|
@ -191,6 +192,28 @@ describe('useInstanceAiStore - runtime registry', () => {
|
|||
expect(store.getRuntime('thread-1')).toBeUndefined();
|
||||
});
|
||||
|
||||
it('keeps the runtime watchers alive after the creating scope stops', async () => {
|
||||
const store = useInstanceAiStore();
|
||||
// The thread view creates the runtime in setup. A Suspense duplicate of the
|
||||
// view is discarded before it mounts, which stops that component scope.
|
||||
const creatorScope = effectScope();
|
||||
const runtime = creatorScope.run(() => store.getOrCreateRuntime('thread-1'));
|
||||
creatorScope.stop();
|
||||
|
||||
runtime?.messages.push({
|
||||
id: 'm1',
|
||||
role: 'user',
|
||||
createdAt: '2026-01-01T00:00:00.000Z',
|
||||
content: '',
|
||||
reasoning: '',
|
||||
isStreaming: false,
|
||||
attachments: [{ type: 'workflow', id: 'wf-1', name: 'My workflow' }],
|
||||
});
|
||||
await nextTick();
|
||||
|
||||
expect(runtime?.producedArtifacts.get('wf-1')?.name).toBe('My workflow');
|
||||
});
|
||||
|
||||
it('syncs a thread into the sidebar list', async () => {
|
||||
const store = useInstanceAiStore();
|
||||
mockEnsureThread.mockResolvedValueOnce({
|
||||
|
|
|
|||
|
|
@ -1,5 +1,14 @@
|
|||
import { defineStore } from 'pinia';
|
||||
import { ref, computed, inject, provide, shallowReactive, type InjectionKey } from 'vue';
|
||||
import {
|
||||
ref,
|
||||
computed,
|
||||
effectScope,
|
||||
inject,
|
||||
provide,
|
||||
shallowReactive,
|
||||
type EffectScope,
|
||||
type InjectionKey,
|
||||
} from 'vue';
|
||||
import { useRootStore } from '@n8n/stores/useRootStore';
|
||||
import { useToast } from '@n8n/composables/useToast';
|
||||
import { useTelemetry } from '@n8n/composables/useTelemetry';
|
||||
|
|
@ -66,6 +75,11 @@ export const useInstanceAiStore = defineStore('instanceAi', () => {
|
|||
|
||||
// --- Thread runtimes ---
|
||||
const runtimes = shallowReactive(new Map<string, ThreadRuntime>());
|
||||
// Detached scopes owning each runtime's watchers. The runtime must outlive the
|
||||
// component that created it: a Suspense duplicate of the thread view can create
|
||||
// it in setup and be discarded, and a component scope would take the watchers
|
||||
// (e.g. the resource registry) down with it.
|
||||
const runtimeScopes = new Map<string, EffectScope>();
|
||||
const runtimeHooks = {
|
||||
onTitleUpdated: (threadId, title) => {
|
||||
for (const thread of localThreadEntries(threadId)) thread.title = title;
|
||||
|
|
@ -81,8 +95,11 @@ export const useInstanceAiStore = defineStore('instanceAi', () => {
|
|||
const existingRuntime = runtimes.get(threadId);
|
||||
if (existingRuntime) return existingRuntime;
|
||||
|
||||
const runtime = createThreadRuntime(threadId, runtimeHooks, projectId);
|
||||
const scope = effectScope(true);
|
||||
const runtime = scope.run(() => createThreadRuntime(threadId, runtimeHooks, projectId));
|
||||
if (!runtime) throw new Error('Failed to create thread runtime');
|
||||
runtimes.set(threadId, runtime);
|
||||
runtimeScopes.set(threadId, scope);
|
||||
return runtime;
|
||||
}
|
||||
|
||||
|
|
@ -95,6 +112,8 @@ export const useInstanceAiStore = defineStore('instanceAi', () => {
|
|||
if (!runtime) return;
|
||||
|
||||
runtime.dispose();
|
||||
runtimeScopes.get(threadId)?.stop();
|
||||
runtimeScopes.delete(threadId);
|
||||
runtimes.delete(threadId);
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user