Message.Context.tsx 1.6 KB

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