Message.Context.tsx64 lines · main
1import { createContext, useContext, type PropsWithChildren } from 'react'
2
3export type AddToolApprovalResponse = (args: {
4 id: string
5 approved: boolean
6 reason?: string
7}) => void | PromiseLike<void>
8
9export interface MessageInfo {
10 id: string
11
12 variant?: 'default' | 'warning'
13
14 isLoading: boolean
15 readOnly?: boolean
16
17 isUserMessage?: boolean
18 isLastMessage?: boolean
19
20 state: 'idle' | 'editing' | 'predecessor-editing'
21 rating?: 'positive' | 'negative' | null
22}
23
24export interface MessageActions {
25 addToolApprovalResponse?: AddToolApprovalResponse
26
27 onDelete: (id: string) => void
28 onEdit: (id: string) => void
29 onCancelEdit: () => void
30 onRate?: (id: string, rating: 'positive' | 'negative', reason?: string) => void
31}
32
33const MessageInfoContext = createContext<MessageInfo | null>(null)
34const MessageActionsContext = createContext<MessageActions | null>(null)
35
36export function useMessageInfoContext() {
37 const ctx = useContext(MessageInfoContext)
38 if (!ctx) {
39 throw Error('useMessageInfoContext must be used within a MessageProvider')
40 }
41 return ctx
42}
43
44export function useMessageActionsContext() {
45 const ctx = useContext(MessageActionsContext)
46 if (!ctx) {
47 throw Error('useMessageActionsContext must be used within a MessageProvider')
48 }
49 return ctx
50}
51
52export function MessageProvider({
53 messageInfo,
54 messageActions,
55 children,
56}: PropsWithChildren<{ messageInfo: MessageInfo; messageActions: MessageActions }>) {
57 return (
58 <MessageInfoContext.Provider value={messageInfo}>
59 <MessageActionsContext.Provider value={messageActions}>
60 {children}
61 </MessageActionsContext.Provider>
62 </MessageInfoContext.Provider>
63 )
64}