assistant-stream.host.spec.ts 2.0 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556
  1. import { describe, expect, it } from 'vitest'
  2. import { LlmAttemptId } from '@deepseek-ai/dsh-llm'
  3. import { SessionAssistantStreamAccumulator } from '../src/assistant-stream.ts'
  4. describe('SessionAssistantStreamAccumulator', () => {
  5. it('replaces stale lifecycles, rejects frame gaps, and caches each baseline', () => {
  6. const accumulator = new SessionAssistantStreamAccumulator()
  7. const empty = accumulator.snapshot()
  8. expect(accumulator.snapshot()).toBe(empty)
  9. accumulator.accept({
  10. type: 'start', attemptId: LlmAttemptId('stale'), revision: 2,
  11. startedTime: 1, turn: 1, step: 1,
  12. })
  13. expect(accumulator.snapshot()).toEqual({ revision: 2 })
  14. accumulator.accept({
  15. type: 'start', attemptId: LlmAttemptId('current'), revision: 1,
  16. startedTime: 2, turn: 2, step: 3,
  17. })
  18. expect(accumulator.snapshot()).toMatchObject({
  19. revision: 1,
  20. activeAttempt: { attemptId: 'current', turn: 2, step: 3, nextIndex: 0, stream: [] },
  21. })
  22. accumulator.accept({
  23. type: 'chunk', attemptId: LlmAttemptId('other'), revision: 2, index: 0,
  24. time: 4, chunk: { type: 'text-delta', index: 0, text: 'lost' },
  25. })
  26. expect(accumulator.snapshot()).toEqual({ revision: 2 })
  27. accumulator.accept({
  28. type: 'start', attemptId: LlmAttemptId('settled'), revision: 3,
  29. startedTime: 3, turn: 2, step: 4,
  30. })
  31. accumulator.accept({
  32. type: 'chunk', attemptId: LlmAttemptId('settled'), revision: 4, index: 0,
  33. time: 5, chunk: { type: 'text-delta', index: 0, text: 'ok' },
  34. })
  35. const active = accumulator.snapshot()
  36. expect(active).toMatchObject({
  37. revision: 4,
  38. activeAttempt: {
  39. attemptId: 'settled', nextIndex: 1,
  40. stream: [{ type: 'text-chunks', time0: 5, index: 0, dt: [], texts: ['ok'] }],
  41. },
  42. })
  43. expect(accumulator.snapshot()).toBe(active)
  44. accumulator.accept({
  45. type: 'end', attemptId: LlmAttemptId('settled'), revision: 5, index: 1,
  46. outcome: { kind: 'abandoned' },
  47. })
  48. expect(accumulator.snapshot()).toEqual({ revision: 5 })
  49. })
  50. })