@lobehub/lobehub 2.0.0-next.212 → 2.0.0-next.213
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.
- package/.github/workflows/auto-i18n.yml +1 -1
- package/.github/workflows/bundle-analyzer.yml +1 -1
- package/.github/workflows/claude-auto-testing.yml +1 -1
- package/.github/workflows/claude-dedupe-issues.yml +1 -1
- package/.github/workflows/claude-issue-triage.yml +1 -1
- package/.github/workflows/claude-translate-comments.yml +1 -1
- package/.github/workflows/claude-translator.yml +1 -1
- package/.github/workflows/claude.yml +1 -1
- package/.github/workflows/desktop-build-electron.yml +2 -2
- package/.github/workflows/e2e.yml +1 -1
- package/.github/workflows/issue-auto-close-duplicates.yml +1 -1
- package/.github/workflows/lighthouse.yml +2 -2
- package/.github/workflows/lock-closed-issues.yml +1 -1
- package/.github/workflows/manual-build-desktop.yml +6 -6
- package/.github/workflows/pr-build-desktop.yml +5 -5
- package/.github/workflows/pr-build-docker.yml +2 -2
- package/.github/workflows/release-desktop-beta.yml +4 -4
- package/.github/workflows/release-docker.yml +2 -2
- package/.github/workflows/release.yml +1 -1
- package/.github/workflows/sync-database-schema.yml +1 -1
- package/.github/workflows/sync.yml +1 -1
- package/.github/workflows/test.yml +5 -5
- package/.github/workflows/verify-desktop-patch.yml +1 -1
- package/CHANGELOG.md +33 -0
- package/changelog/v1.json +9 -0
- package/locales/ar/models.json +35 -4
- package/locales/ar/providers.json +1 -0
- package/locales/bg-BG/models.json +24 -1
- package/locales/bg-BG/providers.json +1 -0
- package/locales/de-DE/models.json +30 -1
- package/locales/de-DE/providers.json +1 -0
- package/locales/en-US/models.json +1 -0
- package/locales/en-US/providers.json +1 -0
- package/locales/es-ES/models.json +32 -1
- package/locales/es-ES/providers.json +1 -0
- package/locales/fa-IR/models.json +48 -1
- package/locales/fa-IR/providers.json +1 -0
- package/locales/fr-FR/models.json +47 -1
- package/locales/fr-FR/providers.json +1 -0
- package/locales/it-IT/models.json +32 -1
- package/locales/it-IT/providers.json +1 -0
- package/locales/ja-JP/models.json +2 -1
- package/locales/ja-JP/providers.json +1 -0
- package/locales/ko-KR/models.json +24 -1
- package/locales/ko-KR/providers.json +1 -0
- package/locales/nl-NL/models.json +46 -1
- package/locales/nl-NL/providers.json +1 -0
- package/locales/pl-PL/models.json +41 -1
- package/locales/pl-PL/providers.json +1 -0
- package/locales/pt-BR/models.json +32 -1
- package/locales/pt-BR/providers.json +1 -0
- package/locales/ru-RU/models.json +54 -2
- package/locales/ru-RU/providers.json +1 -0
- package/locales/tr-TR/models.json +32 -1
- package/locales/tr-TR/providers.json +1 -0
- package/locales/vi-VN/models.json +37 -1
- package/locales/vi-VN/providers.json +1 -0
- package/locales/zh-CN/models.json +24 -3
- package/locales/zh-CN/providers.json +1 -0
- package/locales/zh-TW/models.json +11 -1
- package/locales/zh-TW/providers.json +1 -0
- package/package.json +1 -1
- package/packages/context-engine/src/engine/messages/types.ts +1 -1
- package/packages/model-runtime/src/core/BaseAI.ts +1 -1
- package/packages/model-runtime/src/core/streams/qwen.test.ts +140 -0
- package/packages/model-runtime/src/core/streams/qwen.ts +17 -5
- package/packages/model-runtime/src/types/chat.ts +12 -12
- package/packages/model-runtime/src/types/error.ts +1 -1
- package/packages/model-runtime/src/types/image.ts +1 -1
- package/src/app/[variants]/(main)/chat/features/Conversation/Header/index.tsx +2 -1
- package/src/server/services/comfyui/config/constants.ts +7 -7
- package/src/server/services/comfyui/config/promptToolConst.ts +26 -26
- package/src/server/services/comfyui/utils/promptSplitter.ts +23 -23
- package/src/server/services/comfyui/utils/weightDType.ts +4 -5
|
@@ -481,6 +481,16 @@
|
|
|
481
481
|
"fal-ai/nano-banana.description": "Nano Banana 是 Google 最新、最快且最高效的原生多模態模型,支援透過對話進行圖像生成與編輯。",
|
|
482
482
|
"fal-ai/qwen-image-edit.description": "來自 Qwen 團隊的專業圖像編輯模型,支援語義與外觀編輯,能精準處理中英文文字,並實現風格轉換、物體旋轉等高品質編輯。",
|
|
483
483
|
"fal-ai/qwen-image.description": "來自 Qwen 團隊的強大圖像生成模型,具備優秀的中文文字渲染與多樣化視覺風格。",
|
|
484
|
+
"flux-1-schnell.description": "來自黑森林實驗室的 12B 參數文字轉圖像模型,透過潛在對抗擴散蒸餾技術,在 1 至 4 步內生成高品質圖像。其表現媲美封閉式替代方案,並以 Apache-2.0 授權釋出,供個人、研究與商業用途。",
|
|
485
|
+
"flux-dev.description": "FLUX.1 [dev] 是一款開放權重的蒸餾模型,僅限非商業用途。它保有接近專業水準的圖像品質與指令遵循能力,同時運行更高效,資源使用優於同等大小的標準模型。",
|
|
486
|
+
"flux-kontext-max.description": "最先進的語境圖像生成與編輯技術,結合文字與圖像輸入,實現精準且一致的結果。",
|
|
487
|
+
"flux-kontext-pro.description": "最先進的語境圖像生成與編輯技術,結合文字與圖像輸入,實現精準且一致的結果。",
|
|
488
|
+
"flux-merged.description": "FLUX.1-merged 結合了「DEV」版本的深層特徵與「Schnell」版本的高速優勢,拓展性能極限並擴大應用範圍。",
|
|
489
|
+
"flux-pro-1.1-ultra.description": "支援 4MP 輸出的超高解析度圖像生成,10 秒內產出清晰圖像。",
|
|
490
|
+
"flux-pro-1.1.description": "升級版專業級圖像生成模型,具備卓越圖像品質與精準提示遵循能力。",
|
|
491
|
+
"flux-pro.description": "頂級商業圖像生成模型,擁有無與倫比的圖像品質與多樣化輸出能力。",
|
|
492
|
+
"flux-schnell.description": "FLUX.1 [schnell] 是最先進的開源少步驟模型,超越同類競品,甚至優於如 Midjourney v6.0 與 DALL-E 3(HD)等強大非蒸餾模型。其精細調校保留預訓練多樣性,顯著提升視覺品質、指令遵循、尺寸與比例變化、字體處理與輸出多樣性。",
|
|
493
|
+
"flux.1-schnell.description": "FLUX.1-schnell 是一款高效能圖像生成模型,支援快速多風格輸出。",
|
|
484
494
|
"gemini-flash-latest.description": "Gemini Flash 最新版本",
|
|
485
495
|
"gemini-flash-lite-latest.description": "Gemini Flash-Lite 最新版本",
|
|
486
496
|
"gemini-pro-latest.description": "Gemini Pro 最新版本",
|
|
@@ -746,4 +756,4 @@
|
|
|
746
756
|
"zai/glm-4.5.description": "GLM-4.5 系列專為代理設計。旗艦版 GLM-4.5 結合推理、編碼與代理能力,總參數 355B(啟用 32B),提供混合推理系統的雙模式運行。",
|
|
747
757
|
"zai/glm-4.5v.description": "GLM-4.5V 建構於 GLM-4.5-Air 基礎上,延續 GLM-4.1V-Thinking 技術,並以強大的 106B MoE 架構擴展能力。",
|
|
748
758
|
"zenmux/auto.description": "ZenMux 自動路由會根據您的請求,從支援的選項中選擇性價比最高、效能最佳的模型。"
|
|
749
|
-
}
|
|
759
|
+
}
|
|
@@ -63,6 +63,7 @@
|
|
|
63
63
|
"volcengine.description": "字節跳動的模型服務平台,提供安全、功能豐富且具成本效益的模型存取,並支援資料、微調、推理與評估的端到端工具鏈。",
|
|
64
64
|
"wenxin.description": "文心是一個企業級的基礎模型與 AI 原生應用開發平台,提供生成式 AI 模型與應用流程的端到端工具。",
|
|
65
65
|
"xai.description": "xAI 致力於加速科學發現,目標是深化人類對宇宙的理解。",
|
|
66
|
+
"xiaomimimo.description": "小米 MiMo 提供一項支援 OpenAI 相容 API 的對話模型服務。mimo-v2-flash 模型支援深度推理、串流輸出、函式呼叫、256K 上下文視窗,以及最多 128K 的輸出。",
|
|
66
67
|
"xinference.description": "Xorbits Inference(Xinference)是一個開源平台,簡化 AI 模型的運行與整合,支援在本地或雲端運行開源 LLM、嵌入模型與多模態模型,打造強大的 AI 應用。",
|
|
67
68
|
"zenmux.description": "ZenMux 是一個統一的 AI 聚合平台,支援 OpenAI、Anthropic、Google VertexAI 等,具備靈活路由功能,便於模型切換與管理。",
|
|
68
69
|
"zeroone.description": "01.AI 推動以人為本的 AI 2.0 革命,透過大型語言模型創造經濟與社會價值,構建全新 AI 生態與商業模式。",
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@lobehub/lobehub",
|
|
3
|
-
"version": "2.0.0-next.
|
|
3
|
+
"version": "2.0.0-next.213",
|
|
4
4
|
"description": "LobeHub - an open-source,comprehensive AI Agent framework that supports speech synthesis, multimodal, and extensible Function Call plugin system. Supports one-click free deployment of your private ChatGPT/LLM web application.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"framework",
|
|
@@ -90,7 +90,7 @@ export interface UserMemoryIdentityItem {
|
|
|
90
90
|
description?: string | null;
|
|
91
91
|
id?: string;
|
|
92
92
|
role?: string | null;
|
|
93
|
-
/** Identity type: personal (
|
|
93
|
+
/** Identity type: personal (role), professional (occupation), demographic (attribute) */
|
|
94
94
|
type?: 'demographic' | 'personal' | 'professional' | string | null;
|
|
95
95
|
[key: string]: unknown;
|
|
96
96
|
}
|
|
@@ -36,7 +36,7 @@ export interface LobeRuntimeAI {
|
|
|
36
36
|
options?: TextToSpeechOptions,
|
|
37
37
|
) => Promise<ArrayBuffer>;
|
|
38
38
|
|
|
39
|
-
//
|
|
39
|
+
// Model management related interface
|
|
40
40
|
pullModel?(params: PullModelParams, options?: ModelRequestOptions): Promise<Response>;
|
|
41
41
|
}
|
|
42
42
|
/* eslint-enabled */
|
|
@@ -479,6 +479,146 @@ describe('QwenAIStream', () => {
|
|
|
479
479
|
`data: [{"function":{"arguments":"","name":"get_weather"},"id":"call_123","index":0,"type":"function"}]\n\n`,
|
|
480
480
|
]);
|
|
481
481
|
});
|
|
482
|
+
|
|
483
|
+
it('should handle mixed text content followed by streaming tool calls (DeepSeek style)', async () => {
|
|
484
|
+
// This test simulates the stream pattern from DeepSeek models via Qwen API
|
|
485
|
+
// where text content is streamed first, followed by incremental tool call chunks
|
|
486
|
+
const mockOpenAIStream = new ReadableStream({
|
|
487
|
+
start(controller) {
|
|
488
|
+
// Text content chunks with role in first chunk
|
|
489
|
+
controller.enqueue({
|
|
490
|
+
choices: [
|
|
491
|
+
{
|
|
492
|
+
delta: { content: '看来', role: 'assistant' },
|
|
493
|
+
finish_reason: null,
|
|
494
|
+
index: 0,
|
|
495
|
+
},
|
|
496
|
+
],
|
|
497
|
+
id: 'chatcmpl-4f901cb2-91bc-9763-a2c8-3ed58e9f4075',
|
|
498
|
+
model: 'deepseek-v3',
|
|
499
|
+
object: 'chat.completion.chunk',
|
|
500
|
+
created: 1767574524,
|
|
501
|
+
});
|
|
502
|
+
controller.enqueue({
|
|
503
|
+
choices: [
|
|
504
|
+
{
|
|
505
|
+
delta: { content: '我的' },
|
|
506
|
+
finish_reason: null,
|
|
507
|
+
index: 0,
|
|
508
|
+
},
|
|
509
|
+
],
|
|
510
|
+
id: 'chatcmpl-4f901cb2-91bc-9763-a2c8-3ed58e9f4075',
|
|
511
|
+
model: 'deepseek-v3',
|
|
512
|
+
object: 'chat.completion.chunk',
|
|
513
|
+
created: 1767574524,
|
|
514
|
+
});
|
|
515
|
+
controller.enqueue({
|
|
516
|
+
choices: [
|
|
517
|
+
{
|
|
518
|
+
delta: { content: '函数调用格式有误。' },
|
|
519
|
+
finish_reason: null,
|
|
520
|
+
index: 0,
|
|
521
|
+
},
|
|
522
|
+
],
|
|
523
|
+
id: 'chatcmpl-4f901cb2-91bc-9763-a2c8-3ed58e9f4075',
|
|
524
|
+
model: 'deepseek-v3',
|
|
525
|
+
object: 'chat.completion.chunk',
|
|
526
|
+
created: 1767574524,
|
|
527
|
+
});
|
|
528
|
+
|
|
529
|
+
// First tool call chunk with id, name, and partial arguments
|
|
530
|
+
controller.enqueue({
|
|
531
|
+
choices: [
|
|
532
|
+
{
|
|
533
|
+
delta: {
|
|
534
|
+
tool_calls: [
|
|
535
|
+
{
|
|
536
|
+
id: 'call_ff00c42325d74b979990cb',
|
|
537
|
+
type: 'function',
|
|
538
|
+
function: {
|
|
539
|
+
name: 'modelscope-time____get_current_time____mcp',
|
|
540
|
+
arguments: '{"',
|
|
541
|
+
},
|
|
542
|
+
index: 0,
|
|
543
|
+
},
|
|
544
|
+
],
|
|
545
|
+
},
|
|
546
|
+
finish_reason: null,
|
|
547
|
+
index: 0,
|
|
548
|
+
},
|
|
549
|
+
],
|
|
550
|
+
id: 'chatcmpl-4f901cb2-91bc-9763-a2c8-3ed58e9f4075',
|
|
551
|
+
model: 'deepseek-v3',
|
|
552
|
+
object: 'chat.completion.chunk',
|
|
553
|
+
created: 1767574524,
|
|
554
|
+
});
|
|
555
|
+
|
|
556
|
+
// Subsequent tool call chunk with only incremental arguments (no id)
|
|
557
|
+
controller.enqueue({
|
|
558
|
+
choices: [
|
|
559
|
+
{
|
|
560
|
+
delta: {
|
|
561
|
+
tool_calls: [
|
|
562
|
+
{
|
|
563
|
+
type: 'function',
|
|
564
|
+
function: {
|
|
565
|
+
arguments: 'timezone":"America/New_York"}',
|
|
566
|
+
},
|
|
567
|
+
index: 0,
|
|
568
|
+
},
|
|
569
|
+
],
|
|
570
|
+
},
|
|
571
|
+
finish_reason: null,
|
|
572
|
+
index: 0,
|
|
573
|
+
},
|
|
574
|
+
],
|
|
575
|
+
id: 'chatcmpl-4f901cb2-91bc-9763-a2c8-3ed58e9f4075',
|
|
576
|
+
model: 'deepseek-v3',
|
|
577
|
+
object: 'chat.completion.chunk',
|
|
578
|
+
created: 1767574524,
|
|
579
|
+
});
|
|
580
|
+
|
|
581
|
+
controller.close();
|
|
582
|
+
},
|
|
583
|
+
});
|
|
584
|
+
|
|
585
|
+
const onTextMock = vi.fn();
|
|
586
|
+
const onToolCallMock = vi.fn();
|
|
587
|
+
|
|
588
|
+
const protocolStream = QwenAIStream(mockOpenAIStream, {
|
|
589
|
+
callbacks: {
|
|
590
|
+
onText: onTextMock,
|
|
591
|
+
onToolsCalling: onToolCallMock,
|
|
592
|
+
},
|
|
593
|
+
});
|
|
594
|
+
|
|
595
|
+
const decoder = new TextDecoder();
|
|
596
|
+
const chunks = [];
|
|
597
|
+
|
|
598
|
+
// @ts-ignore
|
|
599
|
+
for await (const chunk of protocolStream) {
|
|
600
|
+
chunks.push(decoder.decode(chunk, { stream: true }));
|
|
601
|
+
}
|
|
602
|
+
|
|
603
|
+
// Verify complete chunks array
|
|
604
|
+
expect(chunks).toEqual([
|
|
605
|
+
'id: chatcmpl-4f901cb2-91bc-9763-a2c8-3ed58e9f4075\n',
|
|
606
|
+
'event: text\n',
|
|
607
|
+
'data: "看来"\n\n',
|
|
608
|
+
'id: chatcmpl-4f901cb2-91bc-9763-a2c8-3ed58e9f4075\n',
|
|
609
|
+
'event: text\n',
|
|
610
|
+
'data: "我的"\n\n',
|
|
611
|
+
'id: chatcmpl-4f901cb2-91bc-9763-a2c8-3ed58e9f4075\n',
|
|
612
|
+
'event: text\n',
|
|
613
|
+
'data: "函数调用格式有误。"\n\n',
|
|
614
|
+
'id: chatcmpl-4f901cb2-91bc-9763-a2c8-3ed58e9f4075\n',
|
|
615
|
+
'event: tool_calls\n',
|
|
616
|
+
'data: [{"function":{"arguments":"{\\"","name":"modelscope-time____get_current_time____mcp"},"id":"call_ff00c42325d74b979990cb","index":0,"type":"function"}]\n\n',
|
|
617
|
+
'id: chatcmpl-4f901cb2-91bc-9763-a2c8-3ed58e9f4075\n',
|
|
618
|
+
'event: tool_calls\n',
|
|
619
|
+
'data: [{"function":{"arguments":"timezone\\":\\"America/New_York\\"}","name":null},"id":"call_ff00c42325d74b979990cb","index":0,"type":"function"}]\n\n',
|
|
620
|
+
]);
|
|
621
|
+
});
|
|
482
622
|
});
|
|
483
623
|
|
|
484
624
|
describe('transformQwenStream', () => {
|
|
@@ -70,8 +70,18 @@ export const transformQwenStream = (
|
|
|
70
70
|
|
|
71
71
|
if (item.delta?.tool_calls) {
|
|
72
72
|
return {
|
|
73
|
-
data: item.delta.tool_calls.map(
|
|
74
|
-
|
|
73
|
+
data: item.delta.tool_calls.map((value, index): StreamToolCallChunkData => {
|
|
74
|
+
// Store first tool call's info in streamContext for subsequent chunks
|
|
75
|
+
// (similar pattern to OpenAI stream handling)
|
|
76
|
+
if (streamContext && !streamContext.tool && value.id && value.function?.name) {
|
|
77
|
+
streamContext.tool = {
|
|
78
|
+
id: value.id,
|
|
79
|
+
index: typeof value.index !== 'undefined' ? value.index : index,
|
|
80
|
+
name: value.function.name,
|
|
81
|
+
};
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
return {
|
|
75
85
|
// Qwen models may send tool_calls in two separate chunks:
|
|
76
86
|
// 1. First chunk: {id, name} without arguments
|
|
77
87
|
// 2. Second chunk: {id, arguments} without name
|
|
@@ -81,11 +91,13 @@ export const transformQwenStream = (
|
|
|
81
91
|
arguments: value.function?.arguments ?? '',
|
|
82
92
|
name: value.function?.name ?? null,
|
|
83
93
|
},
|
|
84
|
-
id
|
|
94
|
+
// For incremental chunks without id, use the stored tool id from streamContext
|
|
95
|
+
id:
|
|
96
|
+
value.id || streamContext?.tool?.id || generateToolCallId(index, value.function?.name),
|
|
85
97
|
index: typeof value.index !== 'undefined' ? value.index : index,
|
|
86
98
|
type: value.type || 'function',
|
|
87
|
-
}
|
|
88
|
-
),
|
|
99
|
+
};
|
|
100
|
+
}),
|
|
89
101
|
id: chunk.id,
|
|
90
102
|
type: 'tool_calls',
|
|
91
103
|
} as StreamProtocolToolCallChunk;
|
|
@@ -62,15 +62,15 @@ export interface OpenAIChatMessage {
|
|
|
62
62
|
export interface ChatStreamPayload {
|
|
63
63
|
apiMode?: 'chatCompletion' | 'responses';
|
|
64
64
|
/**
|
|
65
|
-
*
|
|
65
|
+
* Enable context caching
|
|
66
66
|
*/
|
|
67
67
|
enabledContextCaching?: boolean;
|
|
68
68
|
/**
|
|
69
|
-
*
|
|
69
|
+
* Whether to enable search
|
|
70
70
|
*/
|
|
71
71
|
enabledSearch?: boolean;
|
|
72
72
|
/**
|
|
73
|
-
* @title
|
|
73
|
+
* @title Penalty coefficient for reducing repetitiveness in generated text
|
|
74
74
|
* @default 0
|
|
75
75
|
*/
|
|
76
76
|
frequency_penalty?: number;
|
|
@@ -83,23 +83,23 @@ export interface ChatStreamPayload {
|
|
|
83
83
|
*/
|
|
84
84
|
imageResolution?: '1K' | '2K' | '4K';
|
|
85
85
|
/**
|
|
86
|
-
* @title
|
|
86
|
+
* @title Maximum length of generated text
|
|
87
87
|
*/
|
|
88
88
|
max_tokens?: number;
|
|
89
89
|
/**
|
|
90
|
-
* @title
|
|
90
|
+
* @title List of chat messages
|
|
91
91
|
*/
|
|
92
92
|
messages: OpenAIChatMessage[];
|
|
93
93
|
/**
|
|
94
|
-
* @title
|
|
94
|
+
* @title Model name
|
|
95
95
|
*/
|
|
96
96
|
model: string;
|
|
97
97
|
/**
|
|
98
|
-
* @title
|
|
98
|
+
* @title Number of text responses to return
|
|
99
99
|
*/
|
|
100
100
|
n?: number;
|
|
101
101
|
/**
|
|
102
|
-
* @title
|
|
102
|
+
* @title Penalty coefficient for reducing topic variation in generated text
|
|
103
103
|
* @default 0
|
|
104
104
|
*/
|
|
105
105
|
presence_penalty?: number;
|
|
@@ -112,12 +112,12 @@ export interface ChatStreamPayload {
|
|
|
112
112
|
responseMode?: 'stream' | 'json';
|
|
113
113
|
response_format?: ChatResponseFormat;
|
|
114
114
|
/**
|
|
115
|
-
* @title
|
|
115
|
+
* @title Whether to enable streaming requests
|
|
116
116
|
* @default true
|
|
117
117
|
*/
|
|
118
118
|
stream?: boolean;
|
|
119
119
|
/**
|
|
120
|
-
* @title
|
|
120
|
+
* @title Randomness measure for generated text, controls creativity and diversity
|
|
121
121
|
* @default 1
|
|
122
122
|
*/
|
|
123
123
|
temperature?: number;
|
|
@@ -139,13 +139,13 @@ export interface ChatStreamPayload {
|
|
|
139
139
|
tool_choice?: string;
|
|
140
140
|
tools?: ChatCompletionTool[];
|
|
141
141
|
/**
|
|
142
|
-
* @title
|
|
142
|
+
* @title Controls the highest probability single token in generated text
|
|
143
143
|
* @default 1
|
|
144
144
|
*/
|
|
145
145
|
top_p?: number;
|
|
146
146
|
truncation?: 'auto' | 'disabled';
|
|
147
147
|
/**
|
|
148
|
-
* @title Gemini URL
|
|
148
|
+
* @title Gemini URL context fetching tool toggle
|
|
149
149
|
*/
|
|
150
150
|
urlContext?: boolean;
|
|
151
151
|
verbosity?: 'low' | 'medium' | 'high';
|
|
@@ -34,7 +34,7 @@ export type CreateImageResponse = {
|
|
|
34
34
|
modelUsage?: ModelUsage;
|
|
35
35
|
};
|
|
36
36
|
|
|
37
|
-
//
|
|
37
|
+
// New: Runtime interface for authenticated image download support
|
|
38
38
|
export interface AuthenticatedImageRuntime {
|
|
39
39
|
/**
|
|
40
40
|
* Get authentication headers for image download
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
'use client';
|
|
2
2
|
|
|
3
|
+
import { isDesktop } from '@lobechat/const';
|
|
3
4
|
import { Flexbox } from '@lobehub/ui';
|
|
4
5
|
import { cssVar } from 'antd-style';
|
|
5
6
|
import { memo } from 'react';
|
|
@@ -22,7 +23,7 @@ const Header = memo(() => {
|
|
|
22
23
|
}
|
|
23
24
|
right={
|
|
24
25
|
<Flexbox align={'center'} horizontal style={{ backgroundColor: cssVar.colorBgContainer }}>
|
|
25
|
-
<WorkingDirectory />
|
|
26
|
+
{isDesktop && <WorkingDirectory />}
|
|
26
27
|
<NotebookButton />
|
|
27
28
|
<ShareButton />
|
|
28
29
|
<HeaderActions />
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* ComfyUI framework constants configuration
|
|
3
|
-
* Unified management of hardcoded values with environment variable overrides
|
|
3
|
+
* Unified management of hardcoded values with environment variable overrides
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
6
|
/**
|
|
7
|
-
* Default configuration
|
|
8
|
-
*
|
|
7
|
+
* Default configuration
|
|
8
|
+
* Note: BASE_URL no longer handles environment variables, priority is uniformly handled by constructor
|
|
9
9
|
*/
|
|
10
10
|
export const COMFYUI_DEFAULTS = {
|
|
11
11
|
BASE_URL: 'http://localhost:8000',
|
|
@@ -14,8 +14,8 @@ export const COMFYUI_DEFAULTS = {
|
|
|
14
14
|
} as const;
|
|
15
15
|
|
|
16
16
|
/**
|
|
17
|
-
* FLUX model configuration
|
|
18
|
-
* Removed over-engineered dynamic T5 selection, maintain simple fixed configuration
|
|
17
|
+
* FLUX model configuration
|
|
18
|
+
* Removed over-engineered dynamic T5 selection, maintain simple fixed configuration
|
|
19
19
|
*/
|
|
20
20
|
export const FLUX_MODEL_CONFIG = {
|
|
21
21
|
FILENAME_PREFIXES: {
|
|
@@ -40,8 +40,8 @@ export const SD_MODEL_CONFIG = {
|
|
|
40
40
|
} as const;
|
|
41
41
|
|
|
42
42
|
/**
|
|
43
|
-
* Default workflow node parameters
|
|
44
|
-
* Based on 2024 community best practices configuration
|
|
43
|
+
* Default workflow node parameters
|
|
44
|
+
* Based on 2024 community best practices configuration
|
|
45
45
|
*/
|
|
46
46
|
|
|
47
47
|
/**
|
|
@@ -1,16 +1,16 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Prompt Optimizer Configuration
|
|
3
|
-
*
|
|
3
|
+
* Prompt optimizer configuration - for intelligent splitting and optimization of prompts
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
6
|
/**
|
|
7
7
|
* Style keywords configuration - organized by category
|
|
8
|
-
*
|
|
8
|
+
* Style keyword configuration - organized by category for easy maintenance and extension
|
|
9
9
|
*/
|
|
10
10
|
|
|
11
11
|
/* eslint-disable sort-keys-fix/sort-keys-fix */
|
|
12
12
|
export const STYLE_KEYWORDS = {
|
|
13
|
-
// Artists and platforms
|
|
13
|
+
// Artists and platforms
|
|
14
14
|
ARTISTS: [
|
|
15
15
|
'by greg rutkowski',
|
|
16
16
|
'by artgerm',
|
|
@@ -34,7 +34,7 @@ export const STYLE_KEYWORDS = {
|
|
|
34
34
|
'digital painting',
|
|
35
35
|
],
|
|
36
36
|
|
|
37
|
-
// Art styles
|
|
37
|
+
// Art styles
|
|
38
38
|
ART_STYLES: [
|
|
39
39
|
'photorealistic',
|
|
40
40
|
'photo realistic',
|
|
@@ -90,7 +90,7 @@ export const STYLE_KEYWORDS = {
|
|
|
90
90
|
'retrowave',
|
|
91
91
|
],
|
|
92
92
|
|
|
93
|
-
// Lighting effects
|
|
93
|
+
// Lighting effects
|
|
94
94
|
LIGHTING: [
|
|
95
95
|
'dramatic lighting',
|
|
96
96
|
'soft lighting',
|
|
@@ -131,7 +131,7 @@ export const STYLE_KEYWORDS = {
|
|
|
131
131
|
'incandescent',
|
|
132
132
|
],
|
|
133
133
|
|
|
134
|
-
// Photography terms
|
|
134
|
+
// Photography terms
|
|
135
135
|
PHOTOGRAPHY: [
|
|
136
136
|
'depth of field',
|
|
137
137
|
'shallow depth of field',
|
|
@@ -184,7 +184,7 @@ export const STYLE_KEYWORDS = {
|
|
|
184
184
|
'instant photo',
|
|
185
185
|
],
|
|
186
186
|
|
|
187
|
-
// Quality descriptions
|
|
187
|
+
// Quality descriptions
|
|
188
188
|
QUALITY: [
|
|
189
189
|
'high quality',
|
|
190
190
|
'best quality',
|
|
@@ -227,7 +227,7 @@ export const STYLE_KEYWORDS = {
|
|
|
227
227
|
'exquisite',
|
|
228
228
|
],
|
|
229
229
|
|
|
230
|
-
// Rendering and effects
|
|
230
|
+
// Rendering and effects
|
|
231
231
|
RENDERING: [
|
|
232
232
|
'octane render',
|
|
233
233
|
'octane',
|
|
@@ -270,7 +270,7 @@ export const STYLE_KEYWORDS = {
|
|
|
270
270
|
'high dynamic range',
|
|
271
271
|
],
|
|
272
272
|
|
|
273
|
-
// Color and mood
|
|
273
|
+
// Color and mood
|
|
274
274
|
COLOR_MOOD: [
|
|
275
275
|
'vibrant',
|
|
276
276
|
'vibrant colors',
|
|
@@ -330,7 +330,7 @@ export const STYLE_KEYWORDS = {
|
|
|
330
330
|
'gothic atmosphere',
|
|
331
331
|
],
|
|
332
332
|
|
|
333
|
-
// Texture and materials
|
|
333
|
+
// Texture and materials
|
|
334
334
|
TEXTURE_MATERIAL: [
|
|
335
335
|
'glossy',
|
|
336
336
|
'matte',
|
|
@@ -397,7 +397,7 @@ export const STYLE_KEYWORDS = {
|
|
|
397
397
|
|
|
398
398
|
/**
|
|
399
399
|
* Style synonyms mapping for better recognition
|
|
400
|
-
*
|
|
400
|
+
* Synonym mapping to improve recognition accuracy
|
|
401
401
|
*/
|
|
402
402
|
export const STYLE_SYNONYMS: Record<string, string[]> = {
|
|
403
403
|
// Photography variations
|
|
@@ -443,7 +443,7 @@ export const STYLE_SYNONYMS: Record<string, string[]> = {
|
|
|
443
443
|
|
|
444
444
|
/**
|
|
445
445
|
* Compound styles that should be recognized as a whole
|
|
446
|
-
*
|
|
446
|
+
* Compound styles that should be recognized as a complete unit
|
|
447
447
|
*/
|
|
448
448
|
export const COMPOUND_STYLES = [
|
|
449
449
|
// Studio and brand styles
|
|
@@ -536,37 +536,37 @@ export const COMPOUND_STYLES = [
|
|
|
536
536
|
|
|
537
537
|
/**
|
|
538
538
|
* Precise adjective patterns for style extraction
|
|
539
|
-
*
|
|
539
|
+
* Precise adjective patterns for style extraction
|
|
540
540
|
*/
|
|
541
541
|
export const STYLE_ADJECTIVE_PATTERNS = {
|
|
542
|
-
// Visual quality related
|
|
542
|
+
// Visual quality related
|
|
543
543
|
quality:
|
|
544
544
|
/^(sharp|blur(ry)?|clear|crisp|clean|smooth|rough|grainy|noisy|pristine|flawless|perfect|polished)$/i,
|
|
545
545
|
|
|
546
|
-
// Artistic style related
|
|
546
|
+
// Artistic style related
|
|
547
547
|
artistic:
|
|
548
548
|
/^(abstract|surreal|minimal(ist)?|ornate|baroque|gothic|modern|contemporary|traditional|classical|vintage|retro|antique|futuristic|avant-garde)$/i,
|
|
549
549
|
|
|
550
|
-
// Color and lighting
|
|
550
|
+
// Color and lighting
|
|
551
551
|
visual:
|
|
552
552
|
/^(bright|dark|dim|vibrant|vivid|muted|saturated|desaturated|warm|cool|cold|hot|soft|hard|harsh|gentle|subtle|bold|pale|rich|deep)$/i,
|
|
553
553
|
|
|
554
|
-
// Mood and atmosphere
|
|
554
|
+
// Mood and atmosphere
|
|
555
555
|
mood: /^(dramatic|peaceful|chaotic|serene|calm|mysterious|mystical|magical|epic|legendary|heroic|romantic|melancholic|nostalgic|whimsical|playful|serious|solemn|cheerful|gloomy|ominous|eerie|creepy|scary|dreamy|ethereal|fantastical|moody|atmospheric)$/i,
|
|
556
556
|
|
|
557
|
-
// Texture and material
|
|
557
|
+
// Texture and material
|
|
558
558
|
texture:
|
|
559
559
|
/^(metallic|wooden|glass(y)?|crystalline|fabric|leather|plastic|rubber|organic|synthetic|liquid|solid|transparent|translucent|opaque|reflective|matte|glossy|satin|rough|smooth|wet|dry|dusty|rusty|weathered|aged|new|fresh|worn)$/i,
|
|
560
560
|
|
|
561
|
-
// Size and scale
|
|
561
|
+
// Size and scale
|
|
562
562
|
scale:
|
|
563
563
|
/^(tiny|small|medium|large|huge|massive|gigantic|colossal|enormous|microscopic|miniature|oversized|epic-scale|human-scale|intimate|vast|infinite)$/i,
|
|
564
564
|
|
|
565
|
-
// Complexity and detail
|
|
565
|
+
// Complexity and detail
|
|
566
566
|
detail:
|
|
567
567
|
/^(simple|complex|intricate|elaborate|detailed|minimal|advanced|sophisticated|primitive|refined|crude|delicate|robust)$/i,
|
|
568
568
|
|
|
569
|
-
// Professional quality
|
|
569
|
+
// Professional quality
|
|
570
570
|
professional:
|
|
571
571
|
/^(professional|amateur|masterful|skilled|expert|novice|polished|raw|finished|unfinished|complete|incomplete|refined|rough)$/i,
|
|
572
572
|
} as const;
|
|
@@ -575,7 +575,7 @@ export const STYLE_ADJECTIVE_PATTERNS = {
|
|
|
575
575
|
|
|
576
576
|
/**
|
|
577
577
|
* Get all style keywords as a flattened array
|
|
578
|
-
*
|
|
578
|
+
* Get all style keywords as a flattened array
|
|
579
579
|
*/
|
|
580
580
|
export function getAllStyleKeywords(): readonly string[] {
|
|
581
581
|
return Object.values(STYLE_KEYWORDS).flat();
|
|
@@ -583,7 +583,7 @@ export function getAllStyleKeywords(): readonly string[] {
|
|
|
583
583
|
|
|
584
584
|
/**
|
|
585
585
|
* Get all compound styles
|
|
586
|
-
*
|
|
586
|
+
* Get all compound styles
|
|
587
587
|
*/
|
|
588
588
|
export function getCompoundStyles(): readonly string[] {
|
|
589
589
|
return COMPOUND_STYLES;
|
|
@@ -591,7 +591,7 @@ export function getCompoundStyles(): readonly string[] {
|
|
|
591
591
|
|
|
592
592
|
/**
|
|
593
593
|
* Normalize a style term using synonyms
|
|
594
|
-
*
|
|
594
|
+
* Normalize a style term using synonyms
|
|
595
595
|
*/
|
|
596
596
|
export function normalizeStyleTerm(term: string): string {
|
|
597
597
|
const lowerTerm = term.toLowerCase();
|
|
@@ -608,7 +608,7 @@ export function normalizeStyleTerm(term: string): string {
|
|
|
608
608
|
|
|
609
609
|
/**
|
|
610
610
|
* Check if a word matches any style adjective pattern
|
|
611
|
-
*
|
|
611
|
+
* Check if a word matches any style adjective pattern
|
|
612
612
|
*/
|
|
613
613
|
export function isStyleAdjective(word: string): boolean {
|
|
614
614
|
const lowerWord = word.toLowerCase();
|
|
@@ -617,7 +617,7 @@ export function isStyleAdjective(word: string): boolean {
|
|
|
617
617
|
|
|
618
618
|
/**
|
|
619
619
|
* Extract style adjectives from words based on precise patterns
|
|
620
|
-
*
|
|
620
|
+
* Extract style adjectives from words based on precise patterns
|
|
621
621
|
*/
|
|
622
622
|
export function extractStyleAdjectives(words: string[]): string[] {
|
|
623
623
|
return words.filter((word) => isStyleAdjective(word));
|