message-utils.test.ts 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153
  1. import type { UIMessage } from 'ai'
  2. import { describe, expect, it } from 'vitest'
  3. import { prepareMessagesForAPI } from './message-utils'
  4. describe('prepareMessagesForAPI', () => {
  5. it('should limit messages to last 7 entries', () => {
  6. const messages: UIMessage[] = Array.from({ length: 10 }, (_, i) => ({
  7. id: `msg-${i}`,
  8. role: 'user',
  9. parts: [{ type: 'text', text: `Message ${i}` }],
  10. }))
  11. const result = prepareMessagesForAPI(messages)
  12. expect(result).toHaveLength(7)
  13. expect(result[0].parts[0]).toEqual({ type: 'text', text: 'Message 3' })
  14. expect(result[6].parts[0]).toEqual({ type: 'text', text: 'Message 9' })
  15. })
  16. it('should remove results property from assistant messages', () => {
  17. const messages = [
  18. {
  19. id: 'msg-1',
  20. role: 'assistant',
  21. parts: [{ type: 'text', text: 'Response' }],
  22. results: { data: 'some data' },
  23. },
  24. ] as Array<UIMessage & { results?: unknown }>
  25. const result = prepareMessagesForAPI(messages)
  26. expect(result).toHaveLength(1)
  27. expect(result[0]).not.toHaveProperty('results')
  28. expect(result[0].parts[0]).toEqual({ type: 'text', text: 'Response' })
  29. })
  30. it('should preserve messages without results', () => {
  31. const messages: UIMessage[] = [
  32. {
  33. id: 'msg-1',
  34. role: 'user',
  35. parts: [{ type: 'text', text: 'Question' }],
  36. },
  37. {
  38. id: 'msg-2',
  39. role: 'assistant',
  40. parts: [{ type: 'text', text: 'Answer' }],
  41. },
  42. ]
  43. const result = prepareMessagesForAPI(messages)
  44. expect(result).toHaveLength(2)
  45. expect(result[0]).toEqual(messages[0])
  46. expect(result[1]).toEqual(messages[1])
  47. })
  48. it('should handle empty array', () => {
  49. const messages: UIMessage[] = []
  50. const result = prepareMessagesForAPI(messages)
  51. expect(result).toHaveLength(0)
  52. expect(result).toEqual([])
  53. })
  54. it('should handle array with fewer than 7 messages', () => {
  55. const messages: UIMessage[] = [
  56. { id: 'msg-1', role: 'user', parts: [{ type: 'text', text: 'Message 1' }] },
  57. { id: 'msg-2', role: 'assistant', parts: [{ type: 'text', text: 'Message 2' }] },
  58. { id: 'msg-3', role: 'user', parts: [{ type: 'text', text: 'Message 3' }] },
  59. ]
  60. const result = prepareMessagesForAPI(messages)
  61. expect(result).toHaveLength(3)
  62. expect(result).toEqual(messages)
  63. })
  64. it('should handle array with exactly 7 messages', () => {
  65. const messages: UIMessage[] = Array.from({ length: 7 }, (_, i) => ({
  66. id: `msg-${i}`,
  67. role: i % 2 === 0 ? 'user' : 'assistant',
  68. parts: [{ type: 'text', text: `Message ${i}` }],
  69. }))
  70. const result = prepareMessagesForAPI(messages)
  71. expect(result).toHaveLength(7)
  72. expect(result).toEqual(messages)
  73. })
  74. it('should only remove results from assistant messages, not user messages', () => {
  75. const messages = [
  76. {
  77. id: 'msg-1',
  78. role: 'user',
  79. parts: [{ type: 'text', text: 'Question' }],
  80. results: { data: 'user data' },
  81. },
  82. {
  83. id: 'msg-2',
  84. role: 'assistant',
  85. parts: [{ type: 'text', text: 'Answer' }],
  86. results: { data: 'assistant data' },
  87. },
  88. ] as Array<UIMessage & { results?: unknown }>
  89. const result = prepareMessagesForAPI(messages)
  90. expect(result).toHaveLength(2)
  91. // User message keeps results (not removed by the function)
  92. expect((result[0] as any).results).toEqual({ data: 'user data' })
  93. // Assistant message has results removed
  94. expect(result[1]).not.toHaveProperty('results')
  95. })
  96. it('should handle mixed messages with and without results', () => {
  97. const messages = [
  98. {
  99. id: 'msg-1',
  100. role: 'assistant',
  101. parts: [{ type: 'text', text: 'First' }],
  102. results: { data: 'data1' },
  103. },
  104. {
  105. id: 'msg-2',
  106. role: 'user',
  107. parts: [{ type: 'text', text: 'Second' }],
  108. },
  109. {
  110. id: 'msg-3',
  111. role: 'assistant',
  112. parts: [{ type: 'text', text: 'Third' }],
  113. },
  114. {
  115. id: 'msg-4',
  116. role: 'assistant',
  117. parts: [{ type: 'text', text: 'Fourth' }],
  118. results: { data: 'data2' },
  119. },
  120. ] as Array<UIMessage & { results?: unknown }>
  121. const result = prepareMessagesForAPI(messages)
  122. expect(result).toHaveLength(4)
  123. expect(result[0]).not.toHaveProperty('results')
  124. expect(result[1]).toEqual(messages[1])
  125. expect(result[2]).toEqual(messages[2])
  126. expect(result[3]).not.toHaveProperty('results')
  127. })
  128. })