provider.e2e.ts 2.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960
  1. import { createUserMessage } from '@deepseek-ai/dsh-llm'
  2. import { afterEach, describe, expect, it } from 'vitest'
  3. import { Context } from 'cordis'
  4. import LlmService from '@deepseek-ai/dsh-llm'
  5. import * as LlmDeepSeek from '@deepseek-ai/dsh-llm-deepseek'
  6. import SessionStore, { SessionId } from '@deepseek-ai/dsh-session'
  7. import SessionTitleService from '@deepseek-ai/dsh-session-title'
  8. import * as FirstMessageTitleProvider from '@deepseek-ai/dsh-session-title-first-message-llm'
  9. const contexts: Context[] = []
  10. afterEach(async () => {
  11. await Promise.all(contexts.splice(0).map(ctx => ctx.fiber.dispose()))
  12. })
  13. describe.skipIf(!process.env.DEEPSEEK_API_KEY)('first-message title provider with real DeepSeek API', () => {
  14. it('replaces the fallback with a short model title', async () => {
  15. const ctx = new Context()
  16. contexts.push(ctx)
  17. await ctx.plugin(LlmService)
  18. await ctx.plugin(LlmDeepSeek, { thinking: 'disabled' })
  19. await ctx.plugin(SessionStore)
  20. await ctx.plugin(SessionTitleService, {
  21. fallbackMaxWords: 5,
  22. fallbackMaxBytes: 40,
  23. maxTitleBytes: 80,
  24. })
  25. await ctx.plugin(FirstMessageTitleProvider, {
  26. targetWords: 5,
  27. targetCjkCharacters: 10,
  28. maxInputBytes: 4_096,
  29. maxOutputTokens: 64,
  30. timeoutMs: 60_000,
  31. provider: 'deepseek-official',
  32. model: 'deepseek-v4-flash',
  33. })
  34. const session = ctx.sessions.create(SessionId('real-title-provider'))
  35. session.append('turn/start', {
  36. turn: 1,
  37. trigger: { kind: 'message', source: { kind: 'user' } },
  38. })
  39. const message = session.append('user/message', createUserMessage({
  40. content: [{ type: 'text', text: 'Explain why append-only logs make session titles durable.' }],
  41. source: { kind: 'user' },
  42. }), { surfaceOp: 'append' })
  43. const title = await ctx.sessionTitle.refresh(session)
  44. expect(title).toMatchObject({
  45. messageSeqs: [message.seq],
  46. source: {
  47. kind: 'provider',
  48. provider: 'session-title-first-message-llm',
  49. model: { provider: 'deepseek-official', model: 'deepseek-v4-flash' },
  50. },
  51. })
  52. expect(title?.title.length).toBeGreaterThan(0)
  53. expect(Buffer.byteLength(title?.title ?? '', 'utf8')).toBeLessThanOrEqual(80)
  54. })
  55. })