Skip to content
Closed
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
65 commits
Select commit Hold shift + click to select a range
2f6f6cd
refactor: Use customization to get api base urls (#10871)
mfortman11 Dec 4, 2025
e948d5d
fix: Clean up the default startup logging (#10842)
erichare Dec 4, 2025
b4a54d8
refactor: add code sample customizations (#10884)
mfortman11 Dec 4, 2025
8aec1f3
Fix: lfx serve asyncio event loop error (#10887)
HzaRashid Dec 4, 2025
6cedc28
fix: Update LangflowCounts component to format star and Discord count…
viktoravelino Dec 4, 2025
d5a3124
Add test
jordanrfrazier Dec 5, 2025
e77d924
Revert "Add test"
jordanrfrazier Dec 5, 2025
7a053bd
Fix: update lfx serve tests to mock the .serve() to prevent hanging (…
HzaRashid Dec 5, 2025
7fc4208
fix: correctly raise file not found errors in File GET endpoints (#10…
jordanrfrazier Dec 8, 2025
c0d33c3
fix: image pathing to operate with s3 storage (#10919)
jordanrfrazier Dec 8, 2025
9a7ce34
fix: Add empty input check in ALTKAgent for Anthropic (#10913)
jsntsay Dec 8, 2025
9ed8321
fix: Composio's Freshdesk description error (#10760)
Uday-sidagana Dec 8, 2025
101cbd0
feat: updated Composio Github icon (#10764)
Uday-sidagana Dec 8, 2025
b0bae86
Feat: migrate MCP transport from SSE to streamable http (#10727)
HzaRashid Dec 8, 2025
a209acd
feat: Add a Unified Model Providers configuration (#10565)
HimavarshaVS Dec 9, 2025
12d17dc
fix(ci): Allow prerelease packages and fix runtime type imports (#10945)
Cristhianzl Dec 10, 2025
34216b2
fix: update sidebar icon styles to maintain backward compatibility (#…
viktoravelino Dec 10, 2025
840ec0f
feat: add tenacity retry in openserach (#10917)
edwinjosechittilappilly Dec 10, 2025
f3c08db
fix: Properly set a default Ollama base url (#10940)
erichare Dec 10, 2025
63141c1
feat: Ability to add custom colors for sticky notes. (#10961)
deon-sanchez Dec 10, 2025
2f9136c
fix: Support tool mode in components without inputs (#10959)
erichare Dec 11, 2025
397deff
fix: Proper MCP / Oauth support (#10965)
erichare Dec 11, 2025
70432fe
fix: prevent UI from getting stuck when switching to cURL mode after …
andifilhohub Dec 11, 2025
9463c4a
fix: Ensure dict return for MCP component (#10960)
erichare Dec 11, 2025
bce16ca
feat: Add Correlation ID for CHAIN & LLM Traces in ArizePhoenixTracer…
ialisaleh Dec 11, 2025
9d57aa8
bug: Fix watsonX embedding model selection (#10980)
deon-sanchez Dec 11, 2025
3fed9fe
fix: Add authentication to various endpoints (#10977)
erichare Dec 12, 2025
e9a537b
Fix: cuga integration (#10976)
sami-marreed Dec 12, 2025
24dbc60
Fix: ensure streamable-http session manager is entered and exited fro…
HzaRashid Dec 12, 2025
7ebccb8
Fix: Flowing edge for Boilerplate nodes with default width and height…
olayinkaadelakun Dec 12, 2025
3a41259
feat: Handle error events in OpenAI response streaming (#10844)
edwinjosechittilappilly Dec 12, 2025
f5e68c2
fix: Add graceful subprocess cleanup during shutdown (#10909)
Cristhianzl Dec 12, 2025
a54e508
fix: ruff errors in test openai respons api tests (#11005)
edwinjosechittilappilly Dec 12, 2025
d4ada6b
fix: mcp-proxy process leak (#10988)
phact Dec 12, 2025
757ef6c
feat: Add Hook for Auto Refresh of Model Provider Input (#10996)
deon-sanchez Dec 12, 2025
07a01ad
fix: Disable Local storage option in Write File component for cloud e…
HimavarshaVS Dec 12, 2025
7627660
Fix: disable mcp sse endpoints astra (#11006)
HzaRashid Dec 13, 2025
909bdb1
refactor: Improve image path extraction and validation (#11001)
Cristhianzl Dec 14, 2025
2a5ed55
Fix: Remove hidden from LCAgentComponent (#10984)
olayinkaadelakun Dec 15, 2025
53015c1
fix: cuga update (#11019)
sami-marreed Dec 15, 2025
056a76a
Fix: improve exception handling and status code for disabled endpoint…
HzaRashid Dec 15, 2025
c1c930b
fix: langwatch traces all api endpoints (#11013)
HzaRashid Dec 15, 2025
c970f99
docs: OpenAPI spec content updated without version change (#11032)
github-actions[bot] Dec 16, 2025
ae70c61
fix: Make sure loop inputs are properly handled in research (#11029)
erichare Dec 16, 2025
5ba7fe9
feat: add sliding container infrastructure to playgroundComponent
Nov 30, 2025
2191047
style: add border-radius to flow canvas and update Share button styling
Nov 30, 2025
7766290
fix: add sessionStorage fallback and update types (any -> unknown)
Nov 30, 2025
d4a3b30
feat: add chat-header feature to sliding container
Nov 30, 2025
b192fee
refactor: simplify FlowPageSlidingContainerContent by extracting sess…
Nov 30, 2025
b0b1bed
fix: restore session rename persistence logic from slide-chat-header …
Nov 30, 2025
0c96bbf
chore: revert formatting-only files to main (moved to infrastructure …
Nov 30, 2025
e108cc5
chore: sync formatting files with infrastructure branch
Nov 30, 2025
f956db3
rebase conflicts
Nov 30, 2025
524c54a
removed unecessary comment
Dec 1, 2025
279645b
fix: update messages store when renaming session to prevent content s…
Dec 1, 2025
d6a576f
refactor(ui): remove Sessions icon and adjust padding when playground…
Dec 3, 2025
db147e2
test: add ChatSidebar component tests
Dec 3, 2025
1c56d42
Add animated sidebar transition in playground chat
Dec 9, 2025
7db3329
Revert "Add animated sidebar transition in playground chat"
Dec 9, 2025
72216b2
Restore animated-close and align chat header with mini
Dec 15, 2025
9dd56dd
changes to fix animation using AnimatedConditional
Dec 16, 2025
05fb733
replace hooks
Dec 16, 2025
0704419
remove redundant hook and use use-add-session etc intead
Dec 16, 2025
6989beb
fix(auth): Disallow refresh token access to API endpoints (#10840)
mpawlow Dec 3, 2025
1a66d8a
changes to fix animation using AnimatedConditional
Dec 16, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
rebase conflicts
  • Loading branch information
Olfa Maslah authored and Olfa Maslah committed Dec 16, 2025
commit f956db38f56783282da0dd50ebabfedc321bc233
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
import { useEffect, useMemo, useState } from "react";
import { useDeleteSession } from "@/controllers/API/queries/messages/use-delete-sessions";
import { useGetSessionsFromFlowQuery } from "@/controllers/API/queries/messages/use-get-sessions-from-flow";
import { useGetFlowId } from "./use-get-flow-id";

//Manages session state and selection logic for the chat view.
//Similar to IOModal's session management but simplified.
export function useSessionManagement(isContainerOpen: boolean) {
const currentFlowId = useGetFlowId();

// Fetch sessions only when container is open
const { data: sessionsData, isLoading: sessionsLoading } =
useGetSessionsFromFlowQuery(
{
id: currentFlowId,
},
{
enabled: isContainerOpen,
refetchOnWindowFocus: false,
refetchOnMount: false,
refetchOnReconnect: false,
},
);

// Current selected session (similar to IOModal's visibleSession)
const [currentSessionId, setCurrentSessionId] = useState<string | undefined>(
currentFlowId,
);

const { mutate: deleteSession } = useDeleteSession();

// Process sessions: include default flow ID and ensure no duplicates
const sessions = useMemo(() => {
if (!sessionsData?.sessions) {
return currentFlowId ? [currentFlowId] : [];
}
const sessionList = [...sessionsData.sessions];
if (currentFlowId && !sessionList.includes(currentFlowId)) {
sessionList.unshift(currentFlowId);
}
return sessionList;
}, [sessionsData?.sessions, currentFlowId]);

// Auto-select session when sessions are loaded
// If multiple sessions, select the last one (most recent)
// Only auto-select if no session is currently selected (prevents resetting manually selected/renamed sessions)
useEffect(() => {
if (sessionsLoading) return;

// Only auto-select if no session is currently selected
// This prevents resetting manually selected sessions (e.g., after rename)
if (!currentSessionId) {
if (sessions.length > 0) {
// If multiple sessions, select the last one (most recent)
setCurrentSessionId(sessions[sessions.length - 1]);
} else if (currentFlowId) {
// No sessions, default to flow ID
setCurrentSessionId(currentFlowId);
}
}
// Note: We intentionally don't include currentSessionId in dependencies
// to avoid resetting manually selected sessions when the sessions list updates
}, [sessions, sessionsLoading, currentFlowId]);

const handleSessionSelect = (sessionId: string) => {
setCurrentSessionId(sessionId);
};

const handleNewChat = () => {
const newSessionName = `Session ${new Date().toLocaleString("en-US", {
day: "2-digit",
month: "short",
hour: "2-digit",
minute: "2-digit",
hour12: false,
second: "2-digit",
timeZone: "UTC",
})}`;
setCurrentSessionId(newSessionName);
// TODO: Clear messages or reset chat state
};

const handleDeleteSession = (sessionId: string) => {
if (!sessions.includes(sessionId)) return;

deleteSession(
{ sessionId },
{
onSuccess: () => {
// If deleted session was the current one, switch to another
if (sessionId === currentSessionId) {
const remainingSessions = sessions.filter((s) => s !== sessionId);
if (remainingSessions.length > 0) {
setCurrentSessionId(
remainingSessions[remainingSessions.length - 1],
);
} else {
setCurrentSessionId(currentFlowId);
}
}
},
},
);
};

return {
currentSessionId,
sessions,
isLoading: sessionsLoading,
handleSessionSelect,
handleNewChat,
handleDeleteSession,
currentFlowId,
};
}
Original file line number Diff line number Diff line change
@@ -1,9 +1,7 @@
import { useEffect, useMemo, useState } from "react";
import { useEffect, useState } from "react";
import { ChatHeader } from "@/components/core/playgroundComponent/chat-view/chat-header";
import { ChatSidebar } from "@/components/core/playgroundComponent/chat-view/chat-header/components/chat-sidebar";
import { useGetFlowId } from "@/components/core/playgroundComponent/chat-view/hooks/use-get-flow-id";
import { useDeleteSession } from "@/controllers/API/queries/messages/use-delete-sessions";
import { useGetSessionsFromFlowQuery } from "@/controllers/API/queries/messages/use-get-sessions-from-flow";
import { useSessionManagement } from "@/components/core/playgroundComponent/chat-view/hooks/use-session-management";
import { useSlidingContainerStore } from "../stores/sliding-container-store";

export function FlowPageSlidingContainerContent() {
Expand All @@ -14,158 +12,33 @@ export function FlowPageSlidingContainerContent() {
const setWidth = useSlidingContainerStore((state) => state.setWidth);
const setIsOpen = useSlidingContainerStore((state) => state.setIsOpen);
const isOpen = useSlidingContainerStore((state) => state.isOpen);
const currentFlowId = useGetFlowId();

// Fetch sessions - only when container is open (similar to IOModal)
// Don't refetch on window focus or when expanding - only when container opens or explicitly invalidated
const { data: sessionsData, isLoading: sessionsLoading } =
useGetSessionsFromFlowQuery(
{
id: currentFlowId,
},
{
enabled: isOpen,
refetchOnWindowFocus: false,
refetchOnMount: false,
refetchOnReconnect: false,
},
);

const [currentSessionId, setCurrentSessionId] = useState<string | undefined>(
// Session management logic extracted to custom hook
const {
currentSessionId,
sessions,
handleSessionSelect,
handleNewChat,
handleDeleteSession,
currentFlowId,
);
const [sidebarOpen, setSidebarOpen] = useState(false);
// Track if currentSessionId was manually set (e.g., after rename) to prevent auto-reset
const [isManuallySet, setIsManuallySet] = useState(false);
// Track renamed sessions that aren't in the API response yet
const [renamedSessions, setRenamedSessions] = useState<Set<string>>(
new Set(),
);
const { mutate: deleteSession } = useDeleteSession();
} = useSessionManagement(isOpen);

const sessions = useMemo(() => {
if (!sessionsData?.sessions) {
return [];
}
const sessionList = [...sessionsData.sessions];
// Always include the currentFlowId as the default session if it's not already present
if (currentFlowId && !sessionList.includes(currentFlowId)) {
sessionList.unshift(currentFlowId);
}
// Include renamed sessions that aren't in the API response yet
renamedSessions.forEach((sessionId) => {
if (!sessionList.includes(sessionId)) {
sessionList.push(sessionId);
}
});
return sessionList;
}, [sessionsData?.sessions, currentFlowId, renamedSessions]);

// Determine which session to display: if multiple sessions, show the last one, otherwise show selected or default
// Only auto-update if currentSessionId is not set or was not manually set
// Don't override manually selected sessions (e.g., after rename)
useEffect(() => {
if (sessionsLoading) return;

// Only auto-update if currentSessionId is undefined or was not manually set
// This prevents overriding manually set session IDs (e.g., after rename)
// IMPORTANT: If isManuallySet is true, NEVER auto-update, even if the session isn't in the list
if (!currentSessionId || !isManuallySet) {
if (sessions.length > 0) {
// If we have multiple sessions, show the last one (most recent)
if (sessions.length > 1) {
setCurrentSessionId(sessions[sessions.length - 1]);
} else {
// If only one session, show it
setCurrentSessionId(sessions[0]);
}
setIsManuallySet(false); // Reset flag after auto-update
} else {
// No sessions, default to flow ID
setCurrentSessionId(currentFlowId);
setIsManuallySet(false); // Reset flag after auto-update
}
}
// Note: We intentionally don't include currentSessionId in dependencies
// to avoid resetting manually selected sessions when the sessions list updates
// Also note: isManuallySet being true means we should NEVER auto-update
}, [sessions, sessionsLoading, currentFlowId]);
const [sidebarOpen, setSidebarOpen] = useState(false);

// Auto-open sidebar when entering fullscreen
// Don't reset isManuallySet when expanding - preserve renamed sessions
useEffect(() => {
if (isFullscreen) {
setSidebarOpen(true);
}
}, [isFullscreen]);

const handleNewChat = () => {
// Create a new session name for the new chat
const newSessionName = `Session ${new Date().toLocaleString("en-US", {
day: "2-digit",
month: "short",
hour: "2-digit",
minute: "2-digit",
hour12: false,
second: "2-digit",
timeZone: "UTC",
})}`;
setCurrentSessionId(newSessionName);
setIsManuallySet(true); // Mark as manually set
// TODO: Clear messages or reset chat state
};

const handleSessionSelect = (sessionId: string) => {
setCurrentSessionId(sessionId);
setIsManuallySet(true); // Mark as manually set (important for rename)
// If this is a renamed session (not in the original sessions list), track it
const originalSessions = sessionsData?.sessions || [];
if (!originalSessions.includes(sessionId) && sessionId !== currentFlowId) {
setRenamedSessions((prev) => new Set(prev).add(sessionId));
}
// TODO: Load messages for selected session
};

const handleDeleteSession = (sessionId: string) => {
// Only delete if session exists in the sessions list
if (!sessions.includes(sessionId)) {
return;
}

deleteSession(
{ sessionId },
{
onSuccess: () => {
// If deleted session was the current one, switch to another session
if (sessionId === currentSessionId) {
const remainingSessions = sessions.filter((s) => s !== sessionId);
if (remainingSessions.length > 0) {
// If multiple sessions remain, show the last one
setCurrentSessionId(
remainingSessions[remainingSessions.length - 1],
);
} else {
// Otherwise, default to flow ID
setCurrentSessionId(currentFlowId);
}
}
},
onError: () => {
// Error handling can be added here if needed
},
},
);
};

const handleExitFullscreen = () => {
setIsFullscreen(false);
// Ensure panel stays open and restore to initial width (MIN_WIDTH = 300px)
setIsOpen(true);
setWidth(300);
};

const handleClose = () => {
// Close the panel completely
setIsOpen(false);
setIsFullscreen(false);
};
Expand Down