assembler.spec.ts 2.3 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546
  1. import { describe, expect, it } from 'vitest'
  2. import { BlockAssembler, type StreamChunk } from '@deepseek-ai/dsh-llm'
  3. describe('BlockAssembler', () => {
  4. it('assembles interleaved text, reasoning, and tool-call deltas', () => {
  5. const chunks: StreamChunk[] = [
  6. { type: 'block-start', index: 0, blockType: 'reasoning' },
  7. { type: 'reasoning-delta', index: 0, text: 'thinking…' },
  8. { type: 'block-end', index: 0, block: { type: 'reasoning', text: 'thinking…' } },
  9. { type: 'block-start', index: 1, blockType: 'text' },
  10. { type: 'text-delta', index: 1, text: 'Hello' },
  11. { type: 'text-delta', index: 1, text: ' world' },
  12. { type: 'block-start', index: 2, blockType: 'tool-call' },
  13. { type: 'tool-call-delta', index: 2, id: 'call-1', name: 'echo', argumentsDelta: '{"text":' },
  14. { type: 'tool-call-delta', index: 2, id: 'call-1', argumentsDelta: '"hi"}' },
  15. { type: 'usage', usage: { inputTokens: 10, outputTokens: 5 } },
  16. { type: 'finish', reason: { kind: 'tool-calls' } },
  17. ]
  18. const assembler = new BlockAssembler()
  19. for (const chunk of chunks) assembler.push(chunk)
  20. expect(assembler.blocks()).toEqual([
  21. { type: 'reasoning', text: 'thinking…' },
  22. { type: 'text', text: 'Hello world' },
  23. { type: 'tool-call', id: 'call-1', name: 'echo', arguments: '{"text":"hi"}' },
  24. ])
  25. expect(assembler.usage).toEqual({ inputTokens: 10, outputTokens: 5 })
  26. expect(assembler.finish).toEqual({ kind: 'tool-calls' })
  27. expect(assembler.message().role).toBe('assistant')
  28. })
  29. it('returns the completed block from push() on block-end', () => {
  30. const assembler = new BlockAssembler()
  31. expect(assembler.push({ type: 'block-start', index: 0, blockType: 'text' })).toBeUndefined()
  32. expect(assembler.push({ type: 'text-delta', index: 0, text: 'hi' })).toBeUndefined()
  33. const block = assembler.push({ type: 'block-end', index: 0, block: { type: 'text', text: 'hi' } })
  34. expect(block).toEqual({ type: 'text', text: 'hi' })
  35. })
  36. it('tolerates deltas without explicit block-start/end', () => {
  37. const assembler = new BlockAssembler()
  38. assembler.push({ type: 'text-delta', index: 0, text: 'implicit' })
  39. expect(assembler.blocks()).toEqual([{ type: 'text', text: 'implicit' }])
  40. expect(assembler.finish).toEqual({ kind: 'stop' })
  41. })
  42. })