feat: real SSE streaming for agent chat + data cleanup on startup

SSE Streaming:
- Add POST /api/agent/chat/stream endpoint with real SSE streaming
- Agent.HandleMessageStream() streams final LLM response via onEvent callback
- Tool-calling rounds use non-streaming; tool status sent as 'tool' events
- Frontend uses ReadableStream API instead of fake word-by-word setTimeout
- SSE events: tool (tool execution), delta (text chunk), done (complete), error

Data Maintenance:
- Add cleanupOldData() on server startup (decisions >90d, equity >180d)
- Add CleanOldRecords to DecisionStore and EquityStore
- Add store-level logger for cleanup operations

Exchange Traders:
- Add GetAccountInfo() to Bitget, Bybit, Indodax, KuCoin, Lighter, OKX traders
- Remove unused imports in Aster/Lighter traders
This commit is contained in:
shinchan-zhai
2026-03-23 13:31:09 +08:00
parent 5fc826b4e0
commit bd3d532239
18 changed files with 422 additions and 43 deletions

View File

@@ -247,12 +247,16 @@ func (s *DecisionStore) GetRecordsByDate(traderID string, date time.Time) ([]*De
return records, nil
}
// CleanOldRecords cleans old records from N days ago
// CleanOldRecords cleans old records from N days ago.
// If traderID is empty, cleans records for ALL traders.
func (s *DecisionStore) CleanOldRecords(traderID string, days int) (int64, error) {
cutoffTime := time.Now().AddDate(0, 0, -days)
result := s.db.Where("trader_id = ? AND timestamp < ?", traderID, cutoffTime).
Delete(&DecisionRecordDB{})
query := s.db.Where("timestamp < ?", cutoffTime)
if traderID != "" {
query = query.Where("trader_id = ?", traderID)
}
result := query.Delete(&DecisionRecordDB{})
if result.Error != nil {
return 0, fmt.Errorf("failed to clean old records: %w", result.Error)
}

View File

@@ -117,12 +117,16 @@ func (s *EquityStore) GetAllTradersLatest() (map[string]*EquitySnapshot, error)
return result, nil
}
// CleanOldRecords cleans old records from N days ago
// CleanOldRecords cleans old records from N days ago.
// If traderID is empty, cleans records for ALL traders.
func (s *EquityStore) CleanOldRecords(traderID string, days int) (int64, error) {
cutoffTime := time.Now().AddDate(0, 0, -days)
result := s.db.Where("trader_id = ? AND timestamp < ?", traderID, cutoffTime).
Delete(&EquitySnapshot{})
query := s.db.Where("timestamp < ?", cutoffTime)
if traderID != "" {
query = query.Where("trader_id = ?", traderID)
}
result := query.Delete(&EquitySnapshot{})
if result.Error != nil {
return 0, fmt.Errorf("failed to clean old records: %w", result.Error)
}