import { Score } from '../../db/models' import { ScoreData } from '../../db/models/Score' import { sleep } from '../../utils' import difyService, { CompletionMessagesPayload, DifyRateLimitExceedError, } from '../difyService' import { makePaginate, PaginateOptions, PaginationConnection, } from 'sequelize-cursor-pagination' async function getCompletionMessages( payload: CompletionMessagesPayload ): Promise { const { query, onUpdate, signature } = payload const scoreId = Score.getScoreId(query) const exist = await Score.findOne({ where: { scoreId } }) if (exist) { const { messageId } = exist const words = exist.answer.split(' ').map((word) => ` ${word}`) if (words[0]) { words[0] = words[0].trim() } for (const word of words) { const data = { event: 'message', messageId, signature, answer: word } const message = JSON.stringify(data) onUpdate(`data: ${message}\n\n`) await sleep(20) } const data = { event: 'message_end', messageId, signature } const message = JSON.stringify(data) onUpdate(`data: ${message}\n\n`) return exist } try { const { answer, messageId } = await difyService.getCompletionMessagesByFetchAPI(payload) const [scoreText, score] = Score.getScore(answer) const [row] = await Score.findOrCreate({ where: { scoreId }, defaults: { signature, scoreId, query, answer, messageId, score, scoreText, }, }) return row } catch (e) { if (e instanceof DifyRateLimitExceedError) { const { serveAt } = e const intime = Math.ceil((serveAt - Date.now()) / 1000) throw new Error( `Master is talking with other guys, please try after ${intime}s.` ) } throw e } } // console.log(Tweet.rawAttributes) let paginate: ( this: unknown, queryOptions: PaginateOptions ) => Promise> async function paginateScoreByOrder( after?: string, limit = 10 ): Promise> { if (!paginate) { paginate = makePaginate(Score) } const secondResult = await paginate({ order: [['id', 'DESC']], limit, after, }) const ret: PaginationConnection = { ...secondResult, edges: secondResult.edges.map((edge) => ({ cursor: edge.node.id, node: edge.node.getData(), })), } return ret } async function getScoreById(id: number): Promise { const row = await Score.findByPk(id) if (!row) { throw new Error('Score not found') } return row } const scoreService = { getCompletionMessages, paginateScoreByOrder, getScoreById, } export default scoreService