sessionModel.test.ts 2.5 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455
  1. import { describe, expect, it } from 'vitest'
  2. import { modelForChoiceId, modelForSession, modelSelectionFromSessionInfo } from '@/utils/sessionModel'
  3. import { normalizeSession } from '@/utils/normalize'
  4. import { isOwnedChatSession } from '@/utils/sessionOwnership'
  5. const models = [
  6. { id: 'gpt-5.6-terra', name: 'GPT 5.6 Terra', provider: 'custom' },
  7. { id: 'glm-5.3', name: 'GLM 5.3', provider: 'custom', isDefault: true },
  8. ]
  9. describe('session model selection', () => {
  10. it('restores the saved model case-insensitively instead of the profile default', () => {
  11. expect(modelForSession(models, 'GPT-5.6-terra', 'CUSTOM')).toEqual(models[0])
  12. })
  13. it('keeps an unavailable stored model visible until the user chooses another', () => {
  14. expect(modelForSession(models, 'archived-model', 'legacy')).toEqual({ id: 'archived-model', name: 'archived-model', provider: 'legacy' })
  15. })
  16. it('reads model changes from both session.info payload shapes', () => {
  17. expect(modelSelectionFromSessionInfo({ model: 'gpt-5.6-sol', provider: 'openai-codex' })).toEqual({
  18. model: 'gpt-5.6-sol', provider: 'openai-codex',
  19. })
  20. expect(modelSelectionFromSessionInfo({ info: { model: 'MiniMax-M3', provider: 'minimax' } })).toEqual({
  21. model: 'MiniMax-M3', provider: 'minimax',
  22. })
  23. expect(modelSelectionFromSessionInfo({ info: { provider: 'minimax' } })).toBeUndefined()
  24. })
  25. it('restores the provider from Hermes model_config session details', () => {
  26. expect(normalizeSession({
  27. id: 'session-1', model: 'omni',
  28. model_config: JSON.stringify({ model: 'omni', provider: 'custom:tingly' }),
  29. })).toMatchObject({ model: 'omni', provider: 'custom:tingly' })
  30. })
  31. it('uses server ownership rather than source to separate chats from history', () => {
  32. const ownedIOS = normalizeSession({
  33. id: 'owned-ios', source: 'ios', owned: true, title: '跨端聊天',
  34. })
  35. const unownedWeb = normalizeSession({
  36. id: 'native-web', source: 'web', owned: false, title: '原生历史',
  37. })
  38. expect(isOwnedChatSession(ownedIOS)).toBe(true)
  39. expect(isOwnedChatSession(unownedWeb)).toBe(false)
  40. expect(isOwnedChatSession({ id: 'draft-local', owned: undefined })).toBe(true)
  41. expect(isOwnedChatSession({ id: 'draft-server-history', owned: false })).toBe(false)
  42. })
  43. it('finds a chosen model when its provider contains a colon', () => {
  44. const tinglyModel = { id: 'omni', name: 'Omni', provider: 'Custom:Tingly' }
  45. expect(modelForChoiceId([tinglyModel], 'Custom:Tingly:omni')).toEqual(tinglyModel)
  46. })
  47. })