File size: 4,796 Bytes
f0743f4
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
import React, { createContext, useContext, useMemo } from 'react';
import { useAddedChatContext } from './AddedChatContext';
import { useChatContext } from './ChatContext';

interface MessagesViewContextValue {
  /** Core conversation data */
  conversation: ReturnType<typeof useChatContext>['conversation'];
  conversationId: string | null | undefined;

  /** Submission and control states */
  isSubmitting: ReturnType<typeof useChatContext>['isSubmitting'];
  isSubmittingFamily: boolean;
  abortScroll: ReturnType<typeof useChatContext>['abortScroll'];
  setAbortScroll: ReturnType<typeof useChatContext>['setAbortScroll'];

  /** Message operations */
  ask: ReturnType<typeof useChatContext>['ask'];
  regenerate: ReturnType<typeof useChatContext>['regenerate'];
  handleContinue: ReturnType<typeof useChatContext>['handleContinue'];

  /** Message state management */
  index: ReturnType<typeof useChatContext>['index'];
  latestMessage: ReturnType<typeof useChatContext>['latestMessage'];
  setLatestMessage: ReturnType<typeof useChatContext>['setLatestMessage'];
  getMessages: ReturnType<typeof useChatContext>['getMessages'];
  setMessages: ReturnType<typeof useChatContext>['setMessages'];
}

const MessagesViewContext = createContext<MessagesViewContextValue | undefined>(undefined);

export function MessagesViewProvider({ children }: { children: React.ReactNode }) {
  const chatContext = useChatContext();
  const addedChatContext = useAddedChatContext();

  const {
    ask,
    index,
    regenerate,
    isSubmitting: isSubmittingRoot,
    conversation,
    latestMessage,
    setAbortScroll,
    handleContinue,
    setLatestMessage,
    abortScroll,
    getMessages,
    setMessages,
  } = chatContext;

  const { isSubmitting: isSubmittingAdditional } = addedChatContext;

  /** Memoize conversation-related values */
  const conversationValues = useMemo(
    () => ({
      conversation,
      conversationId: conversation?.conversationId,
    }),
    [conversation],
  );

  /** Memoize submission states */
  const submissionStates = useMemo(
    () => ({
      isSubmitting: isSubmittingRoot,
      isSubmittingFamily: isSubmittingRoot || isSubmittingAdditional,
      abortScroll,
      setAbortScroll,
    }),
    [isSubmittingRoot, isSubmittingAdditional, abortScroll, setAbortScroll],
  );

  /** Memoize message operations (these are typically stable references) */
  const messageOperations = useMemo(
    () => ({
      ask,
      regenerate,
      getMessages,
      setMessages,
      handleContinue,
    }),
    [ask, regenerate, handleContinue, getMessages, setMessages],
  );

  /** Memoize message state values */
  const messageState = useMemo(
    () => ({
      index,
      latestMessage,
      setLatestMessage,
    }),
    [index, latestMessage, setLatestMessage],
  );

  /** Combine all values into final context value */
  const contextValue = useMemo<MessagesViewContextValue>(
    () => ({
      ...conversationValues,
      ...submissionStates,
      ...messageOperations,
      ...messageState,
    }),
    [conversationValues, submissionStates, messageOperations, messageState],
  );

  return (
    <MessagesViewContext.Provider value={contextValue}>{children}</MessagesViewContext.Provider>
  );
}

export function useMessagesViewContext() {
  const context = useContext(MessagesViewContext);
  if (!context) {
    throw new Error('useMessagesViewContext must be used within MessagesViewProvider');
  }
  return context;
}

/** Hook for components that only need conversation data */
export function useMessagesConversation() {
  const { conversation, conversationId } = useMessagesViewContext();
  return useMemo(() => ({ conversation, conversationId }), [conversation, conversationId]);
}

/** Hook for components that only need submission states */
export function useMessagesSubmission() {
  const { isSubmitting, isSubmittingFamily, abortScroll, setAbortScroll } =
    useMessagesViewContext();
  return useMemo(
    () => ({ isSubmitting, isSubmittingFamily, abortScroll, setAbortScroll }),
    [isSubmitting, isSubmittingFamily, abortScroll, setAbortScroll],
  );
}

/** Hook for components that only need message operations */
export function useMessagesOperations() {
  const { ask, regenerate, handleContinue, getMessages, setMessages } = useMessagesViewContext();
  return useMemo(
    () => ({ ask, regenerate, handleContinue, getMessages, setMessages }),
    [ask, regenerate, handleContinue, getMessages, setMessages],
  );
}

/** Hook for components that only need message state */
export function useMessagesState() {
  const { index, latestMessage, setLatestMessage } = useMessagesViewContext();
  return useMemo(
    () => ({ index, latestMessage, setLatestMessage }),
    [index, latestMessage, setLatestMessage],
  );
}