Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
6 changes: 4 additions & 2 deletions client/src/Providers/MessagePartsHostContext.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -22,12 +22,14 @@ import type {
MessagePartsHost,
} from '~/hooks/Chat/contract';
import type { Artifact } from '~/common';
import store, { ptcTraceByToolCallId, ptcTraceKey, sandboxStartingByToolCallId } from '~/store';
import { useMessageContext, useFileMapContext, useAgentsMapContext } from '~/Providers';
import { getAppPartRenderers } from '~/components/Chat/Messages/Content/Parts/slots';
import useSmoothStreaming from '~/hooks/Messages/useSmoothStreaming';
import { ptcTraceByToolCallId, ptcTraceKey } from '~/hooks/SSE/ptc';
import { sandboxStartingByToolCallId } from '~/hooks/SSE/sandbox';
import { showThinkingAtom } from '~/store/showThinking';
import { fontSizeAtom } from '~/store/fontSize';
import store from '~/store';

function useAppMessage(): MessagePartMessage {
const { messageId, isSubmitting, isLatestMessage, nextType } = useMessageContext();
Expand Down Expand Up @@ -119,7 +121,7 @@ export const appMessagePartsHost: MessagePartsHost = {
useToast: () => useToastContext().showToast,
useSandboxStarting: (toolCallId) => useAtomValue(sandboxStartingByToolCallId(toolCallId)),
usePtcTrace: (messageId, toolCallId) =>
useRecoilValue(
useAtomValue(
ptcTraceByToolCallId(toolCallId && messageId ? ptcTraceKey(messageId, toolCallId) : ''),
),
useToolArtifactClaim: (artifactId) => useRecoilState(store.toolArtifactClaim(artifactId)),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
import { isSubmittingFamily, resetSubmitting } from '@librechat/chat/react';
import { Constants, QueryKeys, ContentTypes } from 'librechat-data-provider';
import type { TMessage, TConversation } from 'librechat-data-provider';
import { activeRunFamily } from '~/hooks/SSE/atoms';
import BrowserAudio from '../BrowserAudio';
import store from '~/store';

Expand Down Expand Up @@ -68,7 +69,7 @@ const renderBrowserAudio = ({
initializeState={({ set }) => {
set(store.voice, voiceName);
set(store.conversationByIndex(0), { conversationId } as TConversation);
set(store.activeRunFamily(0), activeRunId);
getDefaultStore().set(activeRunFamily(0), activeRunId);
set(store.audioRunFamily(0), audioRunId);
getDefaultStore().set(isSubmittingFamily(0), isSubmitting);
}}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
import { isSubmittingFamily, resetSubmitting } from '@librechat/chat/react';
import type { TMessage, TConversation } from 'librechat-data-provider';
import { getTTSCacheKey, setCachedTTSAudio, getTTSCacheGeneration } from '~/utils';
import { activeRunFamily } from '~/hooks/SSE/atoms';
import StreamAudio from '../StreamAudio';
import store from '~/store';

Expand Down Expand Up @@ -55,7 +56,7 @@ describe('StreamAudio cache', () => {
initializeState={({ set }) => {
set(store.automaticPlayback, true);
set(store.conversationByIndex(0), { conversationId } as TConversation);
set(store.activeRunFamily(0), 'run-1');
getDefaultStore().set(activeRunFamily(0), 'run-1');
set(store.audioRunFamily(0), null);
getDefaultStore().set(isSubmittingFamily(0), false);
}}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,10 +33,10 @@ import { FOLD_RAIL_CLASSES, ROW_GLYPH_SLOT, TOOL_ROW_CLASSES } from './rows';
import { getOutcomeStatus, isSpanFailed, summarizeSpan } from './outcome';
import useSmoothStreaming from '~/hooks/Messages/useSmoothStreaming';
import useThrottledValue from '~/hooks/Messages/useThrottledValue';
import { sandboxStartingByToolCallId } from '~/hooks/SSE/sandbox';
import { useMCPIconMap, useMCPServerNames } from '~/hooks/MCP';
import { getActivityLabelText } from '~/utils/activityLabels';
import { MCPAppViews } from '~/components/MCPUIResource';
import { sandboxStartingByToolCallId } from '~/store';
import { MessageSurfaceContext } from '../ui/surface';
import useClockFormat from '~/hooks/useClockFormat';
import { cn, getMessageTimestamp } from '~/utils';
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
import React from 'react';
import { RecoilRoot } from 'recoil';
import { render } from '@testing-library/react';
import { createStore, Provider as JotaiProvider } from 'jotai';
import type { PtcTraceEntry } from '~/common';
import { ptcTraceByToolCallId, ptcTraceKey } from '~/store/ptc';
import { ptcTraceByToolCallId, ptcTraceKey } from '~/hooks/SSE/ptc';
import { MessageContext } from '~/Providers/MessageContext';
import ExecuteCode from '../ExecuteCode';
import store from '~/store';
Expand Down Expand Up @@ -147,25 +148,28 @@ describe('ExecuteCode programmatic tool trace', () => {
const TOOL_CALL_ID = 'call_ptc_1';
const MESSAGE_ID = 'response-msg-1';

const renderWithTrace = (entries: PtcTraceEntry[]) =>
render(
<RecoilRoot
initializeState={({ set }) => {
set(store.autoExpandTools, true);
set(ptcTraceByToolCallId(ptcTraceKey(MESSAGE_ID, TOOL_CALL_ID)), { entries, dropped: 0 });
}}
>
<MessageContext.Provider value={{ messageId: MESSAGE_ID, isExpanded: true }}>
<ExecuteCode
initialProgress={0.5}
isSubmitting={true}
toolCallId={TOOL_CALL_ID}
args={{ lang: 'py', code: 'print(1)' }}
output=""
/>
</MessageContext.Provider>
const renderWithTrace = (entries: PtcTraceEntry[]) => {
const traceStore = createStore();
traceStore.set(ptcTraceByToolCallId(ptcTraceKey(MESSAGE_ID, TOOL_CALL_ID)), {
entries,
dropped: 0,
});
return render(
<RecoilRoot initializeState={({ set }) => set(store.autoExpandTools, true)}>
<JotaiProvider store={traceStore}>
<MessageContext.Provider value={{ messageId: MESSAGE_ID, isExpanded: true }}>
<ExecuteCode
initialProgress={0.5}
isSubmitting={true}
toolCallId={TOOL_CALL_ID}
args={{ lang: 'py', code: 'print(1)' }}
output=""
/>
</MessageContext.Provider>
</JotaiProvider>
</RecoilRoot>,
);
};

it('lists the inner tool calls the running program has made', () => {
const { getByText } = renderWithTrace([
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
import React from 'react';
import { RecoilRoot, useSetRecoilState } from 'recoil';
import { RecoilRoot } from 'recoil';
import { render, screen } from '@testing-library/react';
import { useSetAtom, Provider as JotaiProvider } from 'jotai';
import type { PtcTraceEntry } from '~/common';
import { ptcTraceByToolCallId, ptcTraceKey } from '~/store/ptc';
import { ptcTraceByToolCallId, ptcTraceKey } from '~/hooks/SSE/ptc';
import { MessageContext } from '~/Providers/MessageContext';
import PtcToolTrace from '../PtcToolTrace';

Expand Down Expand Up @@ -39,7 +40,7 @@ const MESSAGE_ID = 'response-msg-1';

function renderTrace(entries: PtcTraceEntry[], messageId = MESSAGE_ID, dropped = 0) {
const Seed = () => {
const set = useSetRecoilState(ptcTraceByToolCallId(ptcTraceKey(MESSAGE_ID, TOOL_CALL_ID)));
const set = useSetAtom(ptcTraceByToolCallId(ptcTraceKey(MESSAGE_ID, TOOL_CALL_ID)));
React.useEffect(() => {
if (entries.length > 0) {
set({ entries, dropped });
Expand All @@ -50,10 +51,12 @@ function renderTrace(entries: PtcTraceEntry[], messageId = MESSAGE_ID, dropped =

return render(
<RecoilRoot>
<Seed />
<MessageContext.Provider value={{ messageId, isExpanded: false }}>
<PtcToolTrace toolCallId={TOOL_CALL_ID} />
</MessageContext.Provider>
<JotaiProvider>
<Seed />
<MessageContext.Provider value={{ messageId, isExpanded: false }}>
<PtcToolTrace toolCallId={TOOL_CALL_ID} />
</MessageContext.Provider>
</JotaiProvider>
</RecoilRoot>,
);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,8 @@ import type {
TMessageContentParts,
SearchResultData,
} from 'librechat-data-provider';
import { sandboxStartingByToolCallId } from '~/hooks/SSE/sandbox';
import { resolveAskUserQuestionPart } from '~/utils/approval';
import { sandboxStartingByToolCallId } from '~/store';
import ContentParts from '../ContentParts';
import { getLiveActivity } from '../live';
import * as mcpHooks from '~/hooks/MCP';
Expand Down
3 changes: 2 additions & 1 deletion client/src/hooks/Audio/__tests__/useAutoplayTrigger.spec.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import { isSubmittingFamily, resetSubmitting } from '@librechat/chat/react';
import { Constants, QueryKeys, ContentTypes } from 'librechat-data-provider';
import type { TMessage, TConversation } from 'librechat-data-provider';
import useAutoplayTrigger from '../useAutoplayTrigger';
import { activeRunFamily } from '~/hooks/SSE/atoms';
import store from '~/store';

const conversationId = 'convo-1';
Expand All @@ -30,7 +31,7 @@ const renderTrigger = (message: TMessage) => {
<RecoilRoot
initializeState={({ set }) => {
set(store.conversationByIndex(0), { conversationId } as TConversation);
set(store.activeRunFamily(0), 'run-1');
getDefaultStore().set(activeRunFamily(0), 'run-1');
set(store.audioRunFamily(0), null);
getDefaultStore().set(isSubmittingFamily(0), false);
}}
Expand Down
4 changes: 3 additions & 1 deletion client/src/hooks/Audio/useAutoplayTrigger.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
import { useAtomValue } from 'jotai';
import { useRecoilValue } from 'recoil';
import { useIsSubmitting } from '@librechat/chat/react';
import { getSpeechText } from 'librechat-data-provider';
import type { TMessage } from 'librechat-data-provider';
import { useLatestMessage } from '~/hooks/Messages/useLatestMessage';
import { activeRunFamily } from '~/hooks/SSE/atoms';
import store from '~/store';

export type TAutoplayTrigger = {
Expand All @@ -18,7 +20,7 @@ export type TAutoplayTrigger = {
* speakable text (reasoning alone is not), and its run must not have been played already.
*/
export default function useAutoplayTrigger(index: string | number = 0): TAutoplayTrigger {
const activeRunId = useRecoilValue(store.activeRunFamily(index));
const activeRunId = useAtomValue(activeRunFamily(index));
const audioRunId = useRecoilValue(store.audioRunFamily(index));
const isSubmitting = useIsSubmitting(index);
const latestMessage = useLatestMessage(index);
Expand Down
4 changes: 3 additions & 1 deletion client/src/hooks/Audio/usePauseGlobalAudio.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
import { useCallback } from 'react';
import { useSetAtom } from 'jotai';
import { useRecoilState, useSetRecoilState } from 'recoil';
import { activeRunFamily } from '~/hooks/SSE/atoms';
import { globalAudioId } from '~/common';
import store from '~/store';

function usePauseGlobalAudio(index = 0) {
/* Global Audio Variables */
const setAudioRunId = useSetRecoilState(store.audioRunFamily(index));
const setActiveRunId = useSetRecoilState(store.activeRunFamily(index));
const setActiveRunId = useSetAtom(activeRunFamily(index));
const setGlobalIsPlaying = useSetRecoilState(store.globalAudioPlayingFamily(index));
const setIsGlobalAudioFetching = useSetRecoilState(store.globalAudioFetchingFamily(index));
const [globalAudioURL, setGlobalAudioURL] = useRecoilState(store.globalAudioURLFamily(index));
Expand Down
5 changes: 3 additions & 2 deletions client/src/hooks/Chat/useChatHelpers.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { useCallback, useMemo, useRef, useState } from 'react';
import { useRecoilState } from 'recoil';
import { useQueryClient } from '@tanstack/react-query';
import { useRecoilState, useRecoilValue } from 'recoil';
import { useAtom, useSetAtom, useStore, useAtomValue } from 'jotai';
import { Constants, QueryKeys, isAssistantsEndpoint } from 'librechat-data-provider';
import {
Expand All @@ -19,6 +19,7 @@ import { useLatestMessage, useLatestMessageId } from '~/hooks/Messages/useLatest
import { useAbortStreamMutation, supportsGenerationProtocolV2 } from '~/data-provider';
import { siblingIdxFamily, siblingKey } from '~/components/Chat/Messages/Thread/state';
import { useChatSettings } from '~/Providers/ChatSettingsContext';
import { messageAttachmentsMapAtom } from '~/hooks/SSE/atoms';
import useChatFunctions from '~/hooks/Chat/useChatFunctions';
import useSteerConvert from '~/hooks/Chat/useSteerConvert';
import { resolveAbortSteerTarget } from '~/utils';
Expand All @@ -28,7 +29,7 @@ import { useAbortCleanup } from './abort';
import store from '~/store';

/** The live attachments map the stream and preview polling write. */
const useLiveAttachments = () => useRecoilValue(store.messageAttachmentsMap);
const useLiveAttachments = () => useAtomValue(messageAttachmentsMapAtom);

// this to be set somewhere else
export default function useChatHelpers(index = 0, paramId?: string): ChatContract {
Expand Down
3 changes: 2 additions & 1 deletion client/src/hooks/Config/useClearStates.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import { siblingIdxFamily, siblingKey } from '~/components/Chat/Messages/Thread/
import { showFilesDialogAtom, filesDialogTriggerAtom } from '~/store/filesDialog';
import { showSkillsPopoverFamily } from '~/components/Chat/Input/skillsState';
import { clearLocalStorage } from '~/utils/localStorage';
import { activeRunFamily } from '~/hooks/SSE/atoms';
import store from '~/store';

export default function useClearStates() {
Expand Down Expand Up @@ -72,7 +73,7 @@ export default function useClearStates() {
reset(store.globalAudioURLFamily(key));
reset(store.globalAudioFetchingFamily(key));
reset(store.globalAudioPlayingFamily(key));
reset(store.activeRunFamily(key));
jotaiStore.set(activeRunFamily(key), null);
reset(store.audioRunFamily(key));
jotaiStore.set(siblingIdxFamily(siblingKey(key.toString())), 0);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
import { RecoilRoot } from 'recoil';
import { Tools } from 'librechat-data-provider';
import { render } from '@testing-library/react';
import { Provider as JotaiProvider } from 'jotai';
import type {
TFile,
TAttachment,
Expand Down Expand Up @@ -103,7 +104,9 @@ describe('useAttachmentPreviewSync — #13916 infinite-loop regression', () => {
expect(() =>
render(
<RecoilRoot>
<Consumer />
<JotaiProvider>
<Consumer />
</JotaiProvider>
</RecoilRoot>,
),
).not.toThrow();
Expand Down Expand Up @@ -134,7 +137,9 @@ describe('useAttachmentPreviewSync — #13916 infinite-loop regression', () => {

render(
<RecoilRoot>
<MapProbe />
<JotaiProvider>
<MapProbe />
</JotaiProvider>
</RecoilRoot>,
);

Expand All @@ -157,7 +162,9 @@ describe('useAttachmentPreviewSync — #13916 infinite-loop regression', () => {
expect(() =>
render(
<RecoilRoot>
<Consumer />
<JotaiProvider>
<Consumer />
</JotaiProvider>
</RecoilRoot>,
),
).not.toThrow();
Expand Down
Loading
Loading