index.ts 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126
  1. import { Score } from '../../db/models'
  2. import { ScoreData } from '../../db/models/Score'
  3. import { sleep } from '../../utils'
  4. import difyService, {
  5. CompletionMessagesPayload,
  6. DifyRateLimitExceedError,
  7. } from '../difyService'
  8. import {
  9. makePaginate,
  10. PaginateOptions,
  11. PaginationConnection,
  12. } from 'sequelize-cursor-pagination'
  13. async function getCompletionMessages(
  14. payload: CompletionMessagesPayload
  15. ): Promise<Score> {
  16. const { query, onUpdate, signature } = payload
  17. const scoreId = Score.getScoreId(query)
  18. const exist = await Score.findOne({ where: { scoreId } })
  19. if (exist) {
  20. const { messageId } = exist
  21. const words = exist.answer.split(' ').map((word) => ` ${word}`)
  22. if (words[0]) {
  23. words[0] = words[0].trim()
  24. }
  25. for (const word of words) {
  26. const data = { event: 'message', messageId, signature, answer: word }
  27. const message = JSON.stringify(data)
  28. onUpdate(`data: ${message}\n\n`)
  29. await sleep(20)
  30. }
  31. const data = { event: 'message_end', messageId, signature }
  32. const message = JSON.stringify(data)
  33. onUpdate(`data: ${message}\n\n`)
  34. return exist
  35. }
  36. try {
  37. const { answer, messageId } =
  38. await difyService.getCompletionMessagesByFetchAPI(payload)
  39. const [scoreText, score] = Score.getScore(answer)
  40. const [row] = await Score.findOrCreate({
  41. where: { scoreId },
  42. defaults: {
  43. signature,
  44. scoreId,
  45. query,
  46. answer,
  47. messageId,
  48. score,
  49. scoreText,
  50. },
  51. })
  52. return row
  53. } catch (e) {
  54. if (e instanceof DifyRateLimitExceedError) {
  55. const { serveAt } = e
  56. const intime = Math.ceil((serveAt - Date.now()) / 1000)
  57. throw new Error(
  58. `Master is talking with other guys, please try after ${intime}s.`
  59. )
  60. }
  61. throw e
  62. }
  63. }
  64. // console.log(Tweet.rawAttributes)
  65. let paginate: (
  66. this: unknown,
  67. queryOptions: PaginateOptions<Score>
  68. ) => Promise<PaginationConnection<Score>>
  69. async function paginateScoreByOrder(
  70. after?: string,
  71. limit = 10
  72. ): Promise<PaginationConnection<ScoreData>> {
  73. if (!paginate) {
  74. paginate = makePaginate(Score)
  75. }
  76. const secondResult = await paginate({
  77. order: [['id', 'DESC']],
  78. limit,
  79. after,
  80. })
  81. const ret: PaginationConnection<ScoreData> = {
  82. ...secondResult,
  83. edges: secondResult.edges.map((edge) => ({
  84. cursor: edge.node.id,
  85. node: edge.node.getData(),
  86. })),
  87. }
  88. return ret
  89. }
  90. async function getScoreById(id: number): Promise<Score> {
  91. const row = await Score.findByPk(id)
  92. if (!row) {
  93. throw new Error('Score not found')
  94. }
  95. return row
  96. }
  97. const scoreService = {
  98. getCompletionMessages,
  99. paginateScoreByOrder,
  100. getScoreById,
  101. }
  102. export default scoreService