@lobehub/lobehub 2.0.0-next.165 → 2.0.0-next.167

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (73) hide show
  1. package/.husky/pre-commit +1 -1
  2. package/AGENTS.md +1 -1
  3. package/CHANGELOG.md +50 -0
  4. package/CLAUDE.md +2 -2
  5. package/Dockerfile +44 -52
  6. package/GEMINI.md +1 -1
  7. package/apps/desktop/package.json +4 -4
  8. package/apps/desktop/tsconfig.json +4 -13
  9. package/changelog/v1.json +14 -0
  10. package/docs/development/database-schema.dbml +1 -0
  11. package/locales/ar/models.json +12 -0
  12. package/locales/ar/providers.json +3 -0
  13. package/locales/bg-BG/models.json +12 -0
  14. package/locales/bg-BG/providers.json +3 -0
  15. package/locales/de-DE/models.json +12 -0
  16. package/locales/de-DE/providers.json +3 -0
  17. package/locales/en-US/models.json +12 -0
  18. package/locales/en-US/providers.json +3 -0
  19. package/locales/es-ES/models.json +12 -0
  20. package/locales/es-ES/providers.json +3 -0
  21. package/locales/fa-IR/models.json +12 -0
  22. package/locales/fa-IR/providers.json +3 -0
  23. package/locales/fr-FR/models.json +12 -0
  24. package/locales/fr-FR/providers.json +3 -0
  25. package/locales/it-IT/models.json +12 -0
  26. package/locales/it-IT/providers.json +3 -0
  27. package/locales/ja-JP/models.json +12 -0
  28. package/locales/ja-JP/providers.json +3 -0
  29. package/locales/ko-KR/models.json +12 -0
  30. package/locales/ko-KR/providers.json +3 -0
  31. package/locales/nl-NL/models.json +12 -0
  32. package/locales/nl-NL/providers.json +3 -0
  33. package/locales/pl-PL/models.json +12 -0
  34. package/locales/pl-PL/providers.json +3 -0
  35. package/locales/pt-BR/models.json +12 -0
  36. package/locales/pt-BR/providers.json +3 -0
  37. package/locales/ru-RU/models.json +12 -0
  38. package/locales/ru-RU/providers.json +3 -0
  39. package/locales/tr-TR/models.json +12 -0
  40. package/locales/tr-TR/providers.json +3 -0
  41. package/locales/vi-VN/models.json +12 -0
  42. package/locales/vi-VN/providers.json +3 -0
  43. package/locales/zh-CN/models.json +12 -0
  44. package/locales/zh-CN/providers.json +3 -0
  45. package/locales/zh-TW/models.json +12 -0
  46. package/locales/zh-TW/providers.json +3 -0
  47. package/package.json +43 -43
  48. package/packages/database/migrations/0060_add_user_last_active_at.sql +1 -0
  49. package/packages/database/migrations/meta/0060_snapshot.json +8481 -0
  50. package/packages/database/migrations/meta/_journal.json +8 -1
  51. package/packages/database/src/core/migrations.json +9 -1
  52. package/packages/database/src/schemas/user.ts +1 -0
  53. package/packages/fetch-sse/src/__tests__/headers.test.ts +2 -2
  54. package/packages/model-bank/package.json +1 -0
  55. package/packages/model-bank/src/aiModels/index.ts +3 -0
  56. package/packages/model-bank/src/aiModels/replicate.ts +90 -0
  57. package/packages/model-bank/src/const/modelProvider.ts +1 -0
  58. package/packages/model-runtime/docs/test-coverage.md +5 -5
  59. package/packages/model-runtime/package.json +2 -1
  60. package/packages/model-runtime/src/core/ModelRuntime.ts +11 -1
  61. package/packages/model-runtime/src/providers/replicate/index.ts +424 -0
  62. package/packages/model-runtime/src/runtimeMap.ts +2 -0
  63. package/packages/model-runtime/src/utils/modelParse.ts +13 -0
  64. package/packages/ssrf-safe-fetch/index.browser.ts +22 -2
  65. package/packages/ssrf-safe-fetch/index.ts +30 -6
  66. package/packages/types/src/aiProvider.ts +2 -0
  67. package/src/config/modelProviders/index.ts +3 -0
  68. package/src/config/modelProviders/replicate.ts +23 -0
  69. package/src/server/routers/lambda/__tests__/user.test.ts +2 -0
  70. package/src/server/routers/lambda/market/index.ts +5 -2
  71. package/src/server/routers/lambda/user.ts +5 -0
  72. package/src/services/mcp.ts +1 -0
  73. package/src/store/test-coverage.md +19 -19
@@ -420,7 +420,14 @@
420
420
  "when": 1764858574403,
421
421
  "tag": "0059_add_normalized_email_indexes",
422
422
  "breakpoints": true
423
+ },
424
+ {
425
+ "idx": 60,
426
+ "version": "7",
427
+ "when": 1765437218969,
428
+ "tag": "0060_add_user_last_active_at",
429
+ "breakpoints": true
423
430
  }
424
431
  ],
425
432
  "version": "6"
426
- }
433
+ }
@@ -938,5 +938,13 @@
938
938
  "bps": true,
939
939
  "folderMillis": 1764858574403,
940
940
  "hash": "7838f9938b370867470e5e11807855253d23b11c2ac6aa9e90687844a356c949"
941
+ },
942
+ {
943
+ "sql": [
944
+ "ALTER TABLE \"users\" ADD COLUMN IF NOT EXISTS \"last_active_at\" timestamp with time zone DEFAULT now() NOT NULL;"
945
+ ],
946
+ "bps": true,
947
+ "folderMillis": 1765437218969,
948
+ "hash": "004923916a27bc61294eeb20738f2884f1ca43978a03aa9f0216fc849c98465b"
941
949
  }
942
- ]
950
+ ]
@@ -42,6 +42,7 @@ export const users = pgTable(
42
42
 
43
43
  // better-auth phone number
44
44
  phoneNumberVerified: boolean('phone_number_verified'),
45
+ lastActiveAt: timestamptz('last_active_at').notNull().defaultNow(),
45
46
 
46
47
  ...timestamps,
47
48
  },
@@ -145,7 +145,7 @@ describe('headersToRecord', () => {
145
145
  it('should handle object with special characters in values', () => {
146
146
  // Arrange
147
147
  const headersObj = {
148
- 'authorization': 'Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9',
148
+ 'authorization': 'Bearer test-token',
149
149
  'x-special': 'value with spaces and symbols: !@#$%',
150
150
  };
151
151
 
@@ -154,7 +154,7 @@ describe('headersToRecord', () => {
154
154
 
155
155
  // Assert
156
156
  expect(result).toEqual({
157
- 'authorization': 'Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9',
157
+ 'authorization': 'Bearer test-token',
158
158
  'x-special': 'value with spaces and symbols: !@#$%',
159
159
  });
160
160
  });
@@ -51,6 +51,7 @@
51
51
  "./ppio": "./src/aiModels/ppio.ts",
52
52
  "./qiniu": "./src/aiModels/qiniu.ts",
53
53
  "./qwen": "./src/aiModels/qwen.ts",
54
+ "./replicate": "./src/aiModels/replicate.ts",
54
55
  "./sambanova": "./src/aiModels/sambanova.ts",
55
56
  "./search1api": "./src/aiModels/search1api.ts",
56
57
  "./sensenova": "./src/aiModels/sensenova.ts",
@@ -45,6 +45,7 @@ import { default as perplexity } from './perplexity';
45
45
  import { default as ppio } from './ppio';
46
46
  import { default as qiniu } from './qiniu';
47
47
  import { default as qwen } from './qwen';
48
+ import { default as replicate } from './replicate';
48
49
  import { default as sambanova } from './sambanova';
49
50
  import { default as search1api } from './search1api';
50
51
  import { default as sensenova } from './sensenova';
@@ -133,6 +134,7 @@ export const LOBE_DEFAULT_MODEL_LIST = buildDefaultModelList({
133
134
  ppio,
134
135
  qiniu,
135
136
  qwen,
137
+ replicate,
136
138
  sambanova,
137
139
  search1api,
138
140
  sensenova,
@@ -203,6 +205,7 @@ export { default as perplexity } from './perplexity';
203
205
  export { default as ppio } from './ppio';
204
206
  export { default as qiniu } from './qiniu';
205
207
  export { default as qwen } from './qwen';
208
+ export { default as replicate } from './replicate';
206
209
  export { default as sambanova } from './sambanova';
207
210
  export { default as search1api } from './search1api';
208
211
  export { default as sensenova } from './sensenova';
@@ -0,0 +1,90 @@
1
+ import { AIImageModelCard } from '../types';
2
+
3
+ // Replicate image models
4
+ // https://replicate.com/black-forest-labs
5
+ const imageModels: AIImageModelCard[] = [
6
+ {
7
+ description: 'FLUX 1.1 Pro - 更快更优的 FLUX Pro 版本,具有出色的图像质量和提示词遵循能力。',
8
+ displayName: 'FLUX 1.1 Pro',
9
+ enabled: true,
10
+ id: 'black-forest-labs/flux-1.1-pro',
11
+ parameters: {
12
+ aspectRatio: {
13
+ default: '1:1',
14
+ enum: ['1:1', '16:9', '9:16', '4:3', '3:4', '21:9', '9:21'],
15
+ },
16
+ prompt: { default: '' },
17
+ seed: { default: null },
18
+ },
19
+ pricing: {
20
+ units: [{ name: 'imageGeneration', rate: 0.04, strategy: 'fixed', unit: 'image' }],
21
+ },
22
+ releasedAt: '2024-10-02',
23
+ type: 'image',
24
+ },
25
+ {
26
+ description: 'FLUX Schnell - 专为速度优化的快速图像生成模型。',
27
+ displayName: 'FLUX Schnell',
28
+ enabled: true,
29
+ id: 'black-forest-labs/flux-schnell',
30
+ parameters: {
31
+ aspectRatio: {
32
+ default: '1:1',
33
+ enum: ['1:1', '16:9', '9:16', '4:3', '3:4', '21:9', '9:21'],
34
+ },
35
+ prompt: { default: '' },
36
+ seed: { default: null },
37
+ },
38
+ pricing: {
39
+ units: [{ name: 'imageGeneration', rate: 0.003, strategy: 'fixed', unit: 'image' }],
40
+ },
41
+ releasedAt: '2024-08-01',
42
+ type: 'image',
43
+ },
44
+ {
45
+ description: 'FLUX Dev - FLUX 开发版本,仅供非商业用途使用。',
46
+ displayName: 'FLUX Dev',
47
+ enabled: true,
48
+ id: 'black-forest-labs/flux-dev',
49
+ parameters: {
50
+ aspectRatio: {
51
+ default: '1:1',
52
+ enum: ['1:1', '16:9', '9:16', '4:3', '3:4', '21:9', '9:21'],
53
+ },
54
+ cfg: { default: 3.5, max: 10, min: 1, step: 0.1 },
55
+ prompt: { default: '' },
56
+ seed: { default: null },
57
+ steps: { default: 28, max: 50, min: 1 },
58
+ },
59
+ pricing: {
60
+ units: [{ name: 'imageGeneration', rate: 0.025, strategy: 'fixed', unit: 'image' }],
61
+ },
62
+ releasedAt: '2024-08-01',
63
+ type: 'image',
64
+ },
65
+ {
66
+ description: 'FLUX Pro - 专业版 FLUX 模型,输出高质量图像。',
67
+ displayName: 'FLUX Pro',
68
+ enabled: true,
69
+ id: 'black-forest-labs/flux-pro',
70
+ parameters: {
71
+ aspectRatio: {
72
+ default: '1:1',
73
+ enum: ['1:1', '16:9', '9:16', '4:3', '3:4', '21:9', '9:21'],
74
+ },
75
+ cfg: { default: 3, max: 10, min: 1, step: 0.1 },
76
+ prompt: { default: '' },
77
+ seed: { default: null },
78
+ steps: { default: 25, max: 50, min: 1 },
79
+ },
80
+ pricing: {
81
+ units: [{ name: 'imageGeneration', rate: 0.05, strategy: 'fixed', unit: 'image' }],
82
+ },
83
+ releasedAt: '2024-08-01',
84
+ type: 'image',
85
+ },
86
+ ];
87
+
88
+ export const allModels = [...imageModels];
89
+
90
+ export default allModels;
@@ -46,6 +46,7 @@ export enum ModelProvider {
46
46
  Perplexity = 'perplexity',
47
47
  Qiniu = 'qiniu',
48
48
  Qwen = 'qwen',
49
+ Replicate = 'replicate',
49
50
  SambaNova = 'sambanova',
50
51
  Search1API = 'search1api',
51
52
  SenseNova = 'sensenova',
@@ -390,7 +390,7 @@ bunx vitest run --silent='passed-only' 'src/providers/{provider}/index.test.ts'
390
390
 
391
391
  ```bash
392
392
  # Check TypeScript types (from project root)
393
- cd ../../../ && bun run type-check
393
+ cd ../../../ && bun run typecheck
394
394
 
395
395
  # Or run typecheck for model-runtime only
396
396
  bunx tsc --noEmit
@@ -475,7 +475,7 @@ Based on your development summary, update the following sections:
475
475
  bunx vitest run --silent='passed-only' 'src/providers/{provider}/index.test.ts'
476
476
 
477
477
  # Verify type check still passes
478
- cd ../../../ && bun run type-check
478
+ cd ../../../ && bun run typecheck
479
479
  ```
480
480
 
481
481
  #### Complete Workflow Example
@@ -486,7 +486,7 @@ cd ../../../ && bun run type-check
486
486
  bunx vitest run --silent='passed-only' 'src/providers/example/index.test.ts'
487
487
 
488
488
  # 2. Type/Lint Phase (REQUIRED)
489
- cd ../../../ && bun run type-check # Must pass!
489
+ cd ../../../ && bun run typecheck # Must pass!
490
490
  bunx eslint src/providers/example/ --fix
491
491
 
492
492
  # 3. Coverage Phase
@@ -501,7 +501,7 @@ bunx vitest run --coverage --silent='passed-only'
501
501
 
502
502
  # 6. Final Verification
503
503
  bunx vitest run --silent='passed-only' 'src/providers/example/index.test.ts'
504
- cd ../../../ && bun run type-check
504
+ cd ../../../ && bun run typecheck
505
505
 
506
506
  # 7. Commit
507
507
  git add .
@@ -539,7 +539,7 @@ bunx vitest watch 'src/providers/{provider}/index.test.ts'
539
539
 
540
540
  ```bash
541
541
  # Type check entire project (from project root)
542
- cd ../../../ && bun run type-check
542
+ cd ../../../ && bun run typecheck
543
543
 
544
544
  # Type check model-runtime only
545
545
  bunx tsc --noEmit
@@ -20,6 +20,7 @@
20
20
  "async-retry": "^1.3.3",
21
21
  "debug": "^4.4.3",
22
22
  "model-bank": "workspace:*",
23
- "openai": "^4.104.0"
23
+ "openai": "^4.104.0",
24
+ "replicate": "^1.4.0"
24
25
  }
25
26
  }
@@ -16,7 +16,9 @@ import {
16
16
  TextToImagePayload,
17
17
  TextToSpeechPayload,
18
18
  } from '../types';
19
+ import { AgentRuntimeErrorType } from '../types/error';
19
20
  import { AuthenticatedImageRuntime, CreateImagePayload } from '../types/image';
21
+ import { AgentRuntimeError } from '../utils/createError';
20
22
  import { LobeRuntimeAI } from './BaseAI';
21
23
 
22
24
  export interface AgentChatOptions {
@@ -62,7 +64,15 @@ export class ModelRuntime {
62
64
  * ```
63
65
  */
64
66
  async chat(payload: ChatStreamPayload, options?: ChatMethodOptions) {
65
- return this._runtime.chat!(payload, options);
67
+ if (typeof this._runtime.chat !== 'function') {
68
+ throw AgentRuntimeError.chat({
69
+ error: new Error('Chat is not supported by this provider'),
70
+ errorType: AgentRuntimeErrorType.ProviderBizError,
71
+ provider: payload.provider || 'unknown',
72
+ });
73
+ }
74
+
75
+ return this._runtime.chat(payload, options);
66
76
  }
67
77
 
68
78
  async generateObject(payload: GenerateObjectPayload) {