feat: chatbot
This commit is contained in:
@@ -1429,7 +1429,7 @@ export function useScoreText() {
|
||||
|
||||
// ── AI Chat widget — free-form, read-only, context-aware conversation ────────
|
||||
|
||||
export interface ChatMessage { role: 'user' | 'assistant'; content: string; created_at?: string }
|
||||
export interface ChatMessage { role: 'user' | 'assistant'; content: string; created_at?: string; trade_proposal?: TradeProposalRef | null }
|
||||
|
||||
export const useChatContextBlocks = () =>
|
||||
useQuery({
|
||||
@@ -1446,13 +1446,61 @@ export const useChatHistory = (sessionId: string) =>
|
||||
staleTime: Infinity,
|
||||
})
|
||||
|
||||
export interface TradeProposalRef { id: string; title?: string; underlying?: string; strategy?: string }
|
||||
|
||||
export const useSendChatMessage = () =>
|
||||
useMutation({
|
||||
mutationFn: (body: { session_id: string; message: string; enabled_blocks?: string[]; refresh_context?: boolean }) =>
|
||||
api.post('/ai-chat/', body).then(r => r.data as { reply: string; blocks_included: string[] }),
|
||||
api.post('/ai-chat/', body).then(r => r.data as { reply: string; blocks_included: string[]; trade_proposal: TradeProposalRef | null }),
|
||||
})
|
||||
|
||||
export const useClearChatSession = () =>
|
||||
useMutation({
|
||||
mutationFn: (sessionId: string) => api.post('/ai-chat/clear', { session_id: sessionId }).then(r => r.data),
|
||||
})
|
||||
|
||||
// ── AI Chat widget — trade proposals (pending confirmation) ──────────────────
|
||||
|
||||
export interface AiTradeProposal {
|
||||
id: string
|
||||
session_id: string
|
||||
created_at: string
|
||||
status: 'pending' | 'confirmed' | 'rejected'
|
||||
title: string
|
||||
underlying: string
|
||||
strategy: string
|
||||
asset_class: string
|
||||
expiry_days: number
|
||||
capital_invested: number
|
||||
legs: Array<{ strike: number; option_type: string; quantity: number; position: string }>
|
||||
geo_trigger: string
|
||||
rationale: string
|
||||
portfolio_id?: string | null
|
||||
}
|
||||
|
||||
export const useAiTradeProposals = (status: string = 'pending') =>
|
||||
useQuery({
|
||||
queryKey: ['ai-trade-proposals', status],
|
||||
queryFn: () => api.get('/ai-chat/trade-proposals', { params: { status } }).then(r => r.data.proposals as AiTradeProposal[]),
|
||||
refetchInterval: 30000,
|
||||
})
|
||||
|
||||
export const useConfirmAiTradeProposal = () => {
|
||||
const qc = useQueryClient()
|
||||
return useMutation({
|
||||
mutationFn: (proposalId: string) => api.post(`/ai-chat/trade-proposals/${proposalId}/confirm`).then(r => r.data),
|
||||
onSuccess: () => {
|
||||
qc.invalidateQueries({ queryKey: ['ai-trade-proposals'] })
|
||||
qc.invalidateQueries({ queryKey: ['portfolio'] })
|
||||
qc.invalidateQueries({ queryKey: ['portfolio-summary'] })
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
export const useRejectAiTradeProposal = () => {
|
||||
const qc = useQueryClient()
|
||||
return useMutation({
|
||||
mutationFn: (proposalId: string) => api.post(`/ai-chat/trade-proposals/${proposalId}/reject`).then(r => r.data),
|
||||
onSuccess: () => qc.invalidateQueries({ queryKey: ['ai-trade-proposals'] }),
|
||||
})
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user