From 769e7eebbe8922d2033cb1e46787994ccf590ce9 Mon Sep 17 00:00:00 2001 From: Guilhem Lemouel Date: Wed, 16 Sep 2026 10:08:33 +0200 Subject: [PATCH] fix(chat): list a flow's chats under the path its runs record MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The editor's chat asked for conversations under the path the flow was opened at, while a preview run recorded them under the path being edited. On a flow that has never been deployed those differ from the first keystroke, so every test chat was written somewhere the sidebar never looked and vanished as soon as the list refreshed. `path` is now the path a run records, and what makes the panel a different panel moves to `identity`. They are not the same question: a chat holds conversations, a running turn and the rows it is writing, so it is replaced rather than re-pointed — but replacing it on every keystroke in the path field would throw away the turn being typed alongside. `chatFlowKey` is the flow half of that identity and `chatIdentity` the whole of it, so the panel key and anything filed under the flow cannot drift apart. A conversation keeps the path it was created under, so renaming a flow that already has chats leaves those behind under the old path. That is the trade: the sidebar follows what runs record, and what ran before a rename recorded something else. Co-Authored-By: Claude Opus 5 (1M context) --- .../lib/components/FlowPreviewContent.svelte | 3 +- .../components/flows/content/FlowInput.svelte | 3 +- .../flows/conversations/FlowChat.svelte | 4 +-- .../conversations/FlowChatInterface.svelte | 12 ++++++- .../flows/conversations/FlowChatPanel.svelte | 22 +++++++++---- .../flows/conversations/flowChatProps.ts | 33 +++++++++++++++++++ 6 files changed, 66 insertions(+), 11 deletions(-) diff --git a/frontend/src/lib/components/FlowPreviewContent.svelte b/frontend/src/lib/components/FlowPreviewContent.svelte index 0b2ab01d84..fb0f183cdd 100644 --- a/frontend/src/lib/components/FlowPreviewContent.svelte +++ b/frontend/src/lib/components/FlowPreviewContent.svelte @@ -481,7 +481,8 @@ }} conversationKind="test" frame="boxed" - path={$initialPathStore || fakeInitialPath} + path={$pathStore} + identity={$initialPathStore || fakeInitialPath} inputSchema={flowStore.val.schema} flowModules={flowStore.val.value?.modules} /> diff --git a/frontend/src/lib/components/flows/content/FlowInput.svelte b/frontend/src/lib/components/flows/content/FlowInput.svelte index d41258ff7e..eeeed7a8d2 100644 --- a/frontend/src/lib/components/flows/content/FlowInput.svelte +++ b/frontend/src/lib/components/flows/content/FlowInput.svelte @@ -814,7 +814,8 @@ diff --git a/frontend/src/lib/components/flows/conversations/FlowChatInterface.svelte b/frontend/src/lib/components/flows/conversations/FlowChatInterface.svelte index 47ba31e30b..fe3cd4fcda 100644 --- a/frontend/src/lib/components/flows/conversations/FlowChatInterface.svelte +++ b/frontend/src/lib/components/flows/conversations/FlowChatInterface.svelte @@ -14,6 +14,7 @@ import { useWorkspaceStorageConfigured } from '$lib/components/inputTransformEnv.svelte' import { workspaceStore } from '$lib/stores' import FlowChatModelSettings from './FlowChatModelSettings.svelte' + import { chatFlowKey } from './flowChatProps' import { agentModelGap, agentModelWiringInputs, @@ -33,6 +34,8 @@ /** The flow's modules, used to find which inputs an AI agent step reads directly. */ flowModules?: FlowModule[] path: string + /** What makes this a different chat, when that is not the path — see `FlowChatProps`. */ + identity?: string /** The flow's description, shown under the empty transcript's prompt. */ description?: string wideLayout?: boolean @@ -44,6 +47,7 @@ additionalInputsSchema, flowModules, path, + identity = undefined, description = undefined, wideLayout = false }: Props = $props() @@ -113,8 +117,14 @@ // value, an author's default — is made safe before it reaches the provider. const runInputs = $derived(withoutRejectedEffort(modelWiring, effectiveInputs)) + // Filed under the flow alone, which is what these settings have always been keyed on — + // so the same path in two workspaces shares them, and a model or resource stored by one + // reaches the other. Scoping the key to the workspace is a change of its own: it orphans + // every entry readers already have, and the fix belongs with whatever migrates them. + // `wmill dev` is the one surface whose key moves: it names no flow, so every flow it + // opened shared a single bucket, and the path it does have is the better key. function getStorageKey(): string { - return `${STORAGE_KEY_PREFIX}${path}` + return `${STORAGE_KEY_PREFIX}${chatFlowKey({ path, identity })}` } function loadInputsFromStorage(): Record | null { diff --git a/frontend/src/lib/components/flows/conversations/FlowChatPanel.svelte b/frontend/src/lib/components/flows/conversations/FlowChatPanel.svelte index 5f4036777c..07dd3160e8 100644 --- a/frontend/src/lib/components/flows/conversations/FlowChatPanel.svelte +++ b/frontend/src/lib/components/flows/conversations/FlowChatPanel.svelte @@ -1,8 +1,10 @@