sa2kit 3.4.0 → 3.6.0
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/dist/{chunk-KVYHCGRY.js → chunk-7Z3XR2Y4.js} +552 -263
- package/dist/chunk-7Z3XR2Y4.js.map +1 -0
- package/dist/chunk-XPY45Y75.js +1143 -0
- package/dist/chunk-XPY45Y75.js.map +1 -0
- package/dist/{chunk-YIRPPMCN.mjs → chunk-XSTMLLJV.mjs} +474 -198
- package/dist/chunk-XSTMLLJV.mjs.map +1 -0
- package/dist/chunk-ZJLS5JU5.mjs +1090 -0
- package/dist/chunk-ZJLS5JU5.mjs.map +1 -0
- package/dist/common/aiApi/client/index.d.mts +71 -0
- package/dist/common/aiApi/client/index.d.ts +71 -0
- package/dist/common/aiApi/client/index.js +165 -0
- package/dist/common/aiApi/client/index.js.map +1 -0
- package/dist/common/aiApi/client/index.mjs +151 -0
- package/dist/common/aiApi/client/index.mjs.map +1 -0
- package/dist/common/aiApi/index.d.mts +184 -0
- package/dist/common/aiApi/index.d.ts +184 -0
- package/dist/common/aiApi/index.js +217 -0
- package/dist/common/aiApi/index.mjs +4 -0
- package/dist/common/aiApi/server/index.d.mts +3 -0
- package/dist/common/aiApi/server/index.d.ts +3 -0
- package/dist/common/aiApi/server/index.js +217 -0
- package/dist/common/aiApi/server/index.mjs +4 -0
- package/dist/common/components/index.js +176 -177
- package/dist/common/components/index.mjs +1 -2
- package/dist/common/index.js +2 -3
- package/dist/common/index.mjs +1 -2
- package/dist/index.d.mts +314 -154
- package/dist/index.d.ts +314 -154
- package/dist/index.js +1055 -369
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +1005 -360
- package/dist/index.mjs.map +1 -1
- package/dist/types-CiqMQ-uu.d.mts +166 -0
- package/dist/types-CiqMQ-uu.d.ts +166 -0
- package/package.json +15 -50
- package/dist/chunk-3R6JHA6D.js +0 -120
- package/dist/chunk-3R6JHA6D.js.map +0 -1
- package/dist/chunk-4PJM4752.js +0 -4
- package/dist/chunk-4PJM4752.js.map +0 -1
- package/dist/chunk-7PMT4L4I.js +0 -324
- package/dist/chunk-7PMT4L4I.js.map +0 -1
- package/dist/chunk-FY2X3LYR.mjs +0 -3
- package/dist/chunk-FY2X3LYR.mjs.map +0 -1
- package/dist/chunk-GS4SAW25.mjs +0 -116
- package/dist/chunk-GS4SAW25.mjs.map +0 -1
- package/dist/chunk-HL4H2HF6.js +0 -279
- package/dist/chunk-HL4H2HF6.js.map +0 -1
- package/dist/chunk-IJIQUMAK.mjs +0 -272
- package/dist/chunk-IJIQUMAK.mjs.map +0 -1
- package/dist/chunk-KVYHCGRY.js.map +0 -1
- package/dist/chunk-MMDSZIXD.mjs +0 -286
- package/dist/chunk-MMDSZIXD.mjs.map +0 -1
- package/dist/chunk-N2O3OX5Y.mjs +0 -243
- package/dist/chunk-N2O3OX5Y.mjs.map +0 -1
- package/dist/chunk-RRQ2X26Z.js +0 -106
- package/dist/chunk-RRQ2X26Z.js.map +0 -1
- package/dist/chunk-RVNQI6BI.js +0 -249
- package/dist/chunk-RVNQI6BI.js.map +0 -1
- package/dist/chunk-UJUWDF7M.mjs +0 -336
- package/dist/chunk-UJUWDF7M.mjs.map +0 -1
- package/dist/chunk-VCKXK6V5.js +0 -345
- package/dist/chunk-VCKXK6V5.js.map +0 -1
- package/dist/chunk-VIEXDTNF.mjs +0 -100
- package/dist/chunk-VIEXDTNF.mjs.map +0 -1
- package/dist/chunk-YIRPPMCN.mjs.map +0 -1
- package/dist/common/ai/llm/core/index.d.mts +0 -70
- package/dist/common/ai/llm/core/index.d.ts +0 -70
- package/dist/common/ai/llm/core/index.js +0 -54
- package/dist/common/ai/llm/core/index.mjs +0 -5
- package/dist/common/ai/llm/electron/index.d.mts +0 -6
- package/dist/common/ai/llm/electron/index.d.ts +0 -6
- package/dist/common/ai/llm/electron/index.js +0 -67
- package/dist/common/ai/llm/electron/index.mjs +0 -10
- package/dist/common/ai/llm/index.d.mts +0 -3
- package/dist/common/ai/llm/index.d.ts +0 -3
- package/dist/common/ai/llm/index.js +0 -54
- package/dist/common/ai/llm/index.js.map +0 -1
- package/dist/common/ai/llm/index.mjs +0 -5
- package/dist/common/ai/llm/index.mjs.map +0 -1
- package/dist/common/ai/llm/miniapp/index.d.mts +0 -6
- package/dist/common/ai/llm/miniapp/index.d.ts +0 -6
- package/dist/common/ai/llm/miniapp/index.js +0 -59
- package/dist/common/ai/llm/miniapp/index.js.map +0 -1
- package/dist/common/ai/llm/miniapp/index.mjs +0 -6
- package/dist/common/ai/llm/miniapp/index.mjs.map +0 -1
- package/dist/common/ai/llm/rn/index.d.mts +0 -6
- package/dist/common/ai/llm/rn/index.d.ts +0 -6
- package/dist/common/ai/llm/rn/index.js +0 -59
- package/dist/common/ai/llm/rn/index.js.map +0 -1
- package/dist/common/ai/llm/rn/index.mjs +0 -6
- package/dist/common/ai/llm/rn/index.mjs.map +0 -1
- package/dist/common/ai/llm/ui/electron/index.d.mts +0 -5
- package/dist/common/ai/llm/ui/electron/index.d.ts +0 -5
- package/dist/common/ai/llm/ui/electron/index.js +0 -22
- package/dist/common/ai/llm/ui/electron/index.js.map +0 -1
- package/dist/common/ai/llm/ui/electron/index.mjs +0 -9
- package/dist/common/ai/llm/ui/electron/index.mjs.map +0 -1
- package/dist/common/ai/llm/ui/miniapp/index.d.mts +0 -9
- package/dist/common/ai/llm/ui/miniapp/index.d.ts +0 -9
- package/dist/common/ai/llm/ui/miniapp/index.js +0 -14
- package/dist/common/ai/llm/ui/miniapp/index.js.map +0 -1
- package/dist/common/ai/llm/ui/miniapp/index.mjs +0 -5
- package/dist/common/ai/llm/ui/miniapp/index.mjs.map +0 -1
- package/dist/common/ai/llm/ui/rn/index.d.mts +0 -9
- package/dist/common/ai/llm/ui/rn/index.d.ts +0 -9
- package/dist/common/ai/llm/ui/rn/index.js +0 -14
- package/dist/common/ai/llm/ui/rn/index.js.map +0 -1
- package/dist/common/ai/llm/ui/rn/index.mjs +0 -5
- package/dist/common/ai/llm/ui/rn/index.mjs.map +0 -1
- package/dist/common/ai/llm/ui/web/index.d.mts +0 -15
- package/dist/common/ai/llm/ui/web/index.d.ts +0 -15
- package/dist/common/ai/llm/ui/web/index.js +0 -21
- package/dist/common/ai/llm/ui/web/index.js.map +0 -1
- package/dist/common/ai/llm/ui/web/index.mjs +0 -8
- package/dist/common/ai/llm/ui/web/index.mjs.map +0 -1
- package/dist/common/ai/llm/web/index.d.mts +0 -6
- package/dist/common/ai/llm/web/index.d.ts +0 -6
- package/dist/common/ai/llm/web/index.js +0 -66
- package/dist/common/ai/llm/web/index.js.map +0 -1
- package/dist/common/ai/llm/web/index.mjs +0 -9
- package/dist/common/ai/llm/web/index.mjs.map +0 -1
- package/dist/types-B2rs_jq1.d.mts +0 -38
- package/dist/types-DgACCUpT.d.ts +0 -122
- package/dist/types-DwS2Eg0q.d.ts +0 -38
- package/dist/types-LU_BGSzk.d.mts +0 -122
- /package/dist/common/{ai/llm/core → aiApi}/index.js.map +0 -0
- /package/dist/common/{ai/llm/core → aiApi}/index.mjs.map +0 -0
- /package/dist/common/{ai/llm/electron → aiApi/server}/index.js.map +0 -0
- /package/dist/common/{ai/llm/electron → aiApi/server}/index.mjs.map +0 -0
package/dist/index.js
CHANGED
|
@@ -37541,8 +37541,66 @@ AI\u56DE\u5E94\uFF1A"`;
|
|
|
37541
37541
|
))));
|
|
37542
37542
|
};
|
|
37543
37543
|
|
|
37544
|
-
// src/common/
|
|
37545
|
-
var
|
|
37544
|
+
// src/common/aiApi/types.ts
|
|
37545
|
+
var CORE_LLM_COMPLETION_TASK_ID = "core.llmCompletion";
|
|
37546
|
+
var CORE_STRUCTURED_MULTIMODAL_TASK_ID = "core.structuredMultimodal";
|
|
37547
|
+
var CORE_CONNECTIVITY_TEST_TASK_ID = "core.connectivityTest";
|
|
37548
|
+
|
|
37549
|
+
// src/common/aiApi/resolveConfig.ts
|
|
37550
|
+
var DEFAULT_BASE_URL = "https://api.openai.com/v1";
|
|
37551
|
+
var DEFAULT_TEXT_MODEL = "gpt-4o-mini";
|
|
37552
|
+
var DEFAULT_VISION_MODEL = "gpt-4o-mini";
|
|
37553
|
+
var DEFAULT_AUDIO_MODEL = "whisper-1";
|
|
37554
|
+
var DEFAULT_AUDIO_STRATEGY = "auto";
|
|
37555
|
+
var DEFAULT_TIMEOUT_MS = 6e4;
|
|
37556
|
+
var DEFAULT_MAX_IMAGE_BYTES = 5 * 1024 * 1024;
|
|
37557
|
+
var DEFAULT_MAX_AUDIO_BYTES = 25 * 1024 * 1024;
|
|
37558
|
+
function readEnv(name) {
|
|
37559
|
+
if (typeof process === "undefined" || !process.env) {
|
|
37560
|
+
return "";
|
|
37561
|
+
}
|
|
37562
|
+
return process.env[name]?.trim() ?? "";
|
|
37563
|
+
}
|
|
37564
|
+
function resolveAiConnectionConfig(...sources) {
|
|
37565
|
+
const merged = {};
|
|
37566
|
+
for (const source of sources) {
|
|
37567
|
+
if (!source) continue;
|
|
37568
|
+
Object.assign(merged, source);
|
|
37569
|
+
}
|
|
37570
|
+
const envApiKey = readEnv("AI_API_KEY") || readEnv("OPENAI_API_KEY");
|
|
37571
|
+
const apiKey = merged.apiKey?.trim() || envApiKey;
|
|
37572
|
+
if (!apiKey) {
|
|
37573
|
+
return null;
|
|
37574
|
+
}
|
|
37575
|
+
const baseUrl = merged.baseUrl?.trim() || readEnv("AI_BASE_URL") || DEFAULT_BASE_URL;
|
|
37576
|
+
const visionModel = merged.visionModel?.trim() || readEnv("AI_VISION_MODEL") || merged.model?.trim() || DEFAULT_VISION_MODEL;
|
|
37577
|
+
const textModel = merged.textModel?.trim() || readEnv("AI_TEXT_MODEL") || merged.model?.trim() || visionModel || DEFAULT_TEXT_MODEL;
|
|
37578
|
+
const audioModel = merged.audioModel?.trim() || readEnv("AI_AUDIO_MODEL") || DEFAULT_AUDIO_MODEL;
|
|
37579
|
+
const envAudioStrategy = readEnv("AI_AUDIO_STRATEGY");
|
|
37580
|
+
const audioStrategy = merged.audioStrategy ?? (envAudioStrategy || DEFAULT_AUDIO_STRATEGY);
|
|
37581
|
+
return {
|
|
37582
|
+
apiKey,
|
|
37583
|
+
baseUrl,
|
|
37584
|
+
model: merged.model?.trim() || textModel,
|
|
37585
|
+
textModel,
|
|
37586
|
+
visionModel,
|
|
37587
|
+
audioModel,
|
|
37588
|
+
audioStrategy,
|
|
37589
|
+
timeoutMs: merged.timeoutMs ?? Number(readEnv("AI_TIMEOUT_MS") || DEFAULT_TIMEOUT_MS),
|
|
37590
|
+
maxImageBytes: merged.maxImageBytes ?? Number(readEnv("AI_MAX_IMAGE_BYTES") || DEFAULT_MAX_IMAGE_BYTES),
|
|
37591
|
+
maxAudioBytes: merged.maxAudioBytes ?? Number(readEnv("AI_MAX_AUDIO_BYTES") || DEFAULT_MAX_AUDIO_BYTES)
|
|
37592
|
+
};
|
|
37593
|
+
}
|
|
37594
|
+
function requireAiConnectionConfig(...sources) {
|
|
37595
|
+
const config = resolveAiConnectionConfig(...sources);
|
|
37596
|
+
if (!config) {
|
|
37597
|
+
throw new Error("\u672A\u914D\u7F6E AI API Key\uFF0C\u8BF7\u4F20\u5165 connection / clientSettings \u6216\u8BBE\u7F6E\u73AF\u5883\u53D8\u91CF AI_API_KEY");
|
|
37598
|
+
}
|
|
37599
|
+
return config;
|
|
37600
|
+
}
|
|
37601
|
+
|
|
37602
|
+
// src/common/aiApi/requestJson.ts
|
|
37603
|
+
async function requestJson(options) {
|
|
37546
37604
|
const { url, method = "POST", headers = {}, body, timeoutMs, requestAdapter } = options;
|
|
37547
37605
|
if (requestAdapter) {
|
|
37548
37606
|
return requestAdapter.request({
|
|
@@ -37560,7 +37618,7 @@ var requestJson = async (options) => {
|
|
|
37560
37618
|
const response = await fetch(url, {
|
|
37561
37619
|
method,
|
|
37562
37620
|
headers,
|
|
37563
|
-
body: body ? JSON.stringify(body) : void 0,
|
|
37621
|
+
body: body !== void 0 ? JSON.stringify(body) : void 0,
|
|
37564
37622
|
signal: controller?.signal
|
|
37565
37623
|
});
|
|
37566
37624
|
const text3 = await response.text();
|
|
@@ -37573,8 +37631,9 @@ var requestJson = async (options) => {
|
|
|
37573
37631
|
}
|
|
37574
37632
|
}
|
|
37575
37633
|
if (!response.ok) {
|
|
37576
|
-
const
|
|
37577
|
-
const
|
|
37634
|
+
const record = data;
|
|
37635
|
+
const errorMessage2 = (typeof record?.error === "object" ? record.error?.message : record?.error) || record?.message || `Request failed with status ${response.status}`;
|
|
37636
|
+
const error = new Error(String(errorMessage2));
|
|
37578
37637
|
error.status = response.status;
|
|
37579
37638
|
error.data = data;
|
|
37580
37639
|
throw error;
|
|
@@ -37585,404 +37644,990 @@ var requestJson = async (options) => {
|
|
|
37585
37644
|
clearTimeout(timeoutId);
|
|
37586
37645
|
}
|
|
37587
37646
|
}
|
|
37588
|
-
}
|
|
37647
|
+
}
|
|
37589
37648
|
|
|
37590
|
-
// src/common/
|
|
37649
|
+
// src/common/aiApi/callChat.ts
|
|
37591
37650
|
var DEFAULT_OPENAI_BASE_URL = "https://api.openai.com/v1";
|
|
37592
|
-
var
|
|
37593
|
-
|
|
37594
|
-
|
|
37595
|
-
|
|
37596
|
-
|
|
37597
|
-
|
|
37598
|
-
|
|
37599
|
-
if (!toolCalls || !toolCalls.length) {
|
|
37600
|
-
return void 0;
|
|
37651
|
+
var DEFAULT_TEXT_MODEL2 = "gpt-4o-mini";
|
|
37652
|
+
function joinUrl(base, path) {
|
|
37653
|
+
return `${base.replace(/\/+$/, "")}/${path.replace(/^\/+/, "")}`;
|
|
37654
|
+
}
|
|
37655
|
+
function resolveMessages(input) {
|
|
37656
|
+
if (input.messages?.length) {
|
|
37657
|
+
return input.messages;
|
|
37601
37658
|
}
|
|
37602
|
-
|
|
37603
|
-
|
|
37604
|
-
|
|
37605
|
-
|
|
37606
|
-
|
|
37607
|
-
|
|
37608
|
-
}
|
|
37609
|
-
}));
|
|
37610
|
-
};
|
|
37611
|
-
var normalizeUsage = (usage) => {
|
|
37612
|
-
if (!usage) {
|
|
37613
|
-
return void 0;
|
|
37659
|
+
const messages = [];
|
|
37660
|
+
if (input.systemPrompt?.trim()) {
|
|
37661
|
+
messages.push({ role: "system", content: input.systemPrompt.trim() });
|
|
37662
|
+
}
|
|
37663
|
+
if (input.userPrompt?.trim()) {
|
|
37664
|
+
messages.push({ role: "user", content: input.userPrompt.trim() });
|
|
37614
37665
|
}
|
|
37666
|
+
return messages;
|
|
37667
|
+
}
|
|
37668
|
+
async function callChat(options) {
|
|
37669
|
+
const {
|
|
37670
|
+
baseUrl,
|
|
37671
|
+
apiKey,
|
|
37672
|
+
model,
|
|
37673
|
+
systemPrompt,
|
|
37674
|
+
userPrompt,
|
|
37675
|
+
messages,
|
|
37676
|
+
temperature,
|
|
37677
|
+
maxTokens,
|
|
37678
|
+
topP,
|
|
37679
|
+
stop,
|
|
37680
|
+
timeoutMs = 6e4,
|
|
37681
|
+
requestAdapter
|
|
37682
|
+
} = options;
|
|
37683
|
+
if (!baseUrl?.trim()) {
|
|
37684
|
+
throw new Error("baseUrl \u4E3A\u5FC5\u586B");
|
|
37685
|
+
}
|
|
37686
|
+
if (!apiKey?.trim()) {
|
|
37687
|
+
throw new Error("apiKey \u4E3A\u5FC5\u586B");
|
|
37688
|
+
}
|
|
37689
|
+
const resolvedMessages = resolveMessages({ systemPrompt, userPrompt, messages });
|
|
37690
|
+
if (!resolvedMessages.length) {
|
|
37691
|
+
throw new Error("userPrompt \u6216 messages \u81F3\u5C11\u63D0\u4F9B\u4E00\u9879");
|
|
37692
|
+
}
|
|
37693
|
+
const resolvedModel = model?.trim() || DEFAULT_TEXT_MODEL2;
|
|
37694
|
+
const payload = {
|
|
37695
|
+
model: resolvedModel,
|
|
37696
|
+
messages: resolvedMessages
|
|
37697
|
+
};
|
|
37698
|
+
if (temperature !== void 0) payload.temperature = temperature;
|
|
37699
|
+
if (maxTokens !== void 0) payload.max_tokens = maxTokens;
|
|
37700
|
+
if (topP !== void 0) payload.top_p = topP;
|
|
37701
|
+
if (stop !== void 0) payload.stop = stop;
|
|
37702
|
+
const raw = await requestJson({
|
|
37703
|
+
url: joinUrl(baseUrl.trim(), "chat/completions"),
|
|
37704
|
+
method: "POST",
|
|
37705
|
+
headers: {
|
|
37706
|
+
"Content-Type": "application/json",
|
|
37707
|
+
Authorization: `Bearer ${apiKey.trim()}`
|
|
37708
|
+
},
|
|
37709
|
+
body: payload,
|
|
37710
|
+
timeoutMs,
|
|
37711
|
+
requestAdapter
|
|
37712
|
+
});
|
|
37713
|
+
const content = raw.choices?.[0]?.message?.content ?? "";
|
|
37714
|
+
const usage = raw.usage ? {
|
|
37715
|
+
promptTokens: raw.usage.prompt_tokens,
|
|
37716
|
+
completionTokens: raw.usage.completion_tokens,
|
|
37717
|
+
totalTokens: raw.usage.total_tokens
|
|
37718
|
+
} : void 0;
|
|
37615
37719
|
return {
|
|
37616
|
-
|
|
37617
|
-
|
|
37618
|
-
|
|
37619
|
-
|
|
37620
|
-
};
|
|
37621
|
-
|
|
37622
|
-
|
|
37623
|
-
|
|
37624
|
-
|
|
37625
|
-
|
|
37626
|
-
|
|
37627
|
-
|
|
37720
|
+
content,
|
|
37721
|
+
model: raw.model ?? resolvedModel,
|
|
37722
|
+
usage,
|
|
37723
|
+
raw
|
|
37724
|
+
};
|
|
37725
|
+
}
|
|
37726
|
+
|
|
37727
|
+
// src/common/aiApi/callCompletion.ts
|
|
37728
|
+
async function callCompletion(params, clientSettings) {
|
|
37729
|
+
const config = requireAiConnectionConfig(params.connection, clientSettings);
|
|
37730
|
+
const model = params.model || config.textModel;
|
|
37731
|
+
const result = await callChat({
|
|
37732
|
+
baseUrl: config.baseUrl,
|
|
37733
|
+
apiKey: config.apiKey,
|
|
37734
|
+
model,
|
|
37735
|
+
systemPrompt: params.systemPrompt,
|
|
37736
|
+
userPrompt: params.userPrompt,
|
|
37737
|
+
temperature: params.temperature,
|
|
37738
|
+
maxTokens: params.maxTokens,
|
|
37739
|
+
timeoutMs: config.timeoutMs
|
|
37740
|
+
});
|
|
37741
|
+
return {
|
|
37742
|
+
content: result.content,
|
|
37743
|
+
model: result.model || model,
|
|
37744
|
+
raw: result.raw
|
|
37745
|
+
};
|
|
37746
|
+
}
|
|
37747
|
+
|
|
37748
|
+
// src/common/aiApi/modelHeuristics.ts
|
|
37749
|
+
var NON_CHAT_PATTERNS = [
|
|
37750
|
+
/embed/i,
|
|
37751
|
+
/whisper/i,
|
|
37752
|
+
/tts/i,
|
|
37753
|
+
/dall-e/i,
|
|
37754
|
+
/moderation/i,
|
|
37755
|
+
/realtime/i,
|
|
37756
|
+
/audio/i,
|
|
37757
|
+
/transcrib/i,
|
|
37758
|
+
/sora/i
|
|
37759
|
+
];
|
|
37760
|
+
var VISION_HINT_PATTERNS = [
|
|
37761
|
+
/^gpt-4o/i,
|
|
37762
|
+
/^gpt-4-turbo/i,
|
|
37763
|
+
/^gpt-4-vision/i,
|
|
37764
|
+
/^gpt-4\.1/i,
|
|
37765
|
+
/claude-3/i,
|
|
37766
|
+
/gemini.*(pro|flash|vision)/i,
|
|
37767
|
+
/qwen.*vl/i,
|
|
37768
|
+
/vision/i,
|
|
37769
|
+
/-vl/i,
|
|
37770
|
+
/llava/i,
|
|
37771
|
+
/doubao.*vision/i,
|
|
37772
|
+
/glm-4v/i,
|
|
37773
|
+
/internvl/i,
|
|
37774
|
+
/pixtral/i,
|
|
37775
|
+
/deepseek-vl/i
|
|
37776
|
+
];
|
|
37777
|
+
var PREFERRED_VISION_MODELS = [
|
|
37778
|
+
"gpt-4o-mini",
|
|
37779
|
+
"gpt-4o",
|
|
37780
|
+
"gpt-4-turbo",
|
|
37781
|
+
"gpt-4-vision-preview",
|
|
37782
|
+
"gpt-4.1-mini",
|
|
37783
|
+
"gpt-4.1",
|
|
37784
|
+
"claude-3-5-sonnet-latest",
|
|
37785
|
+
"claude-3-5-haiku-latest",
|
|
37786
|
+
"gemini-2.0-flash",
|
|
37787
|
+
"gemini-1.5-flash",
|
|
37788
|
+
"gemini-1.5-pro",
|
|
37789
|
+
"qwen-vl-max",
|
|
37790
|
+
"qwen2-vl-72b-instruct"
|
|
37791
|
+
];
|
|
37792
|
+
function isChatModel(id) {
|
|
37793
|
+
return !NON_CHAT_PATTERNS.some((pattern) => pattern.test(id));
|
|
37794
|
+
}
|
|
37795
|
+
var NATIVE_AUDIO_CHAT_PATTERNS = [
|
|
37796
|
+
/^gpt-4o/i,
|
|
37797
|
+
/^gpt-4-turbo/i,
|
|
37798
|
+
/^gpt-4\.1/i,
|
|
37799
|
+
/gemini-2\.0/i,
|
|
37800
|
+
/gemini-1\.5/i
|
|
37801
|
+
];
|
|
37802
|
+
var STT_MODEL_PATTERNS = [/whisper/i, /transcrib/i, /sensevoice/i, /paraformer/i];
|
|
37803
|
+
function isLikelyNativeAudioChatModel(id) {
|
|
37804
|
+
const trimmed = id.trim();
|
|
37805
|
+
if (!trimmed) return false;
|
|
37806
|
+
if (STT_MODEL_PATTERNS.some((pattern) => pattern.test(trimmed))) return false;
|
|
37807
|
+
return NATIVE_AUDIO_CHAT_PATTERNS.some((pattern) => pattern.test(trimmed));
|
|
37808
|
+
}
|
|
37809
|
+
function isLikelySttModel(id) {
|
|
37810
|
+
return STT_MODEL_PATTERNS.some((pattern) => pattern.test(id.trim()));
|
|
37811
|
+
}
|
|
37812
|
+
function filterSttModels(modelIds) {
|
|
37813
|
+
return modelIds.filter(isLikelySttModel).sort((a, b) => a.localeCompare(b));
|
|
37814
|
+
}
|
|
37815
|
+
var PREFERRED_STT_MODELS = ["whisper-1", "whisper-large-v3", "whisper-large-v3-turbo"];
|
|
37816
|
+
function pickDefaultSttModel(modelIds, current) {
|
|
37817
|
+
const sttModels = filterSttModels(modelIds);
|
|
37818
|
+
if (sttModels.length === 0) return void 0;
|
|
37819
|
+
const trimmedCurrent = current?.trim();
|
|
37820
|
+
if (trimmedCurrent && sttModels.includes(trimmedCurrent)) {
|
|
37821
|
+
return trimmedCurrent;
|
|
37822
|
+
}
|
|
37823
|
+
for (const preferred of PREFERRED_STT_MODELS) {
|
|
37824
|
+
const match = sttModels.find((id) => id === preferred || id.startsWith(`${preferred}-`));
|
|
37825
|
+
if (match) return match;
|
|
37826
|
+
}
|
|
37827
|
+
return sttModels[0];
|
|
37828
|
+
}
|
|
37829
|
+
function isLikelyVisionModel(id) {
|
|
37830
|
+
return VISION_HINT_PATTERNS.some((pattern) => pattern.test(id));
|
|
37831
|
+
}
|
|
37832
|
+
var TEXT_ONLY_MODEL_PATTERNS = [
|
|
37833
|
+
/^deepseek-chat/i,
|
|
37834
|
+
/^deepseek-reasoner/i,
|
|
37835
|
+
/^deepseek-r1/i,
|
|
37836
|
+
/^deepseek-v[34](?!.*vl)/i,
|
|
37837
|
+
/^gpt-3\.5/i,
|
|
37838
|
+
/^o1-mini/i,
|
|
37839
|
+
/^o3-mini/i
|
|
37840
|
+
];
|
|
37841
|
+
function isKnownTextOnlyModel(id) {
|
|
37842
|
+
const trimmed = id.trim();
|
|
37843
|
+
if (!trimmed) return false;
|
|
37844
|
+
return TEXT_ONLY_MODEL_PATTERNS.some((pattern) => pattern.test(trimmed));
|
|
37845
|
+
}
|
|
37846
|
+
function filterChatModels(modelIds) {
|
|
37847
|
+
return modelIds.filter(isChatModel).sort((a, b) => a.localeCompare(b));
|
|
37848
|
+
}
|
|
37849
|
+
function filterVisionModels(modelIds) {
|
|
37850
|
+
return filterChatModels(modelIds).filter((id) => isLikelyVisionModel(id) && !isKnownTextOnlyModel(id)).sort((a, b) => a.localeCompare(b));
|
|
37851
|
+
}
|
|
37852
|
+
function matchesPreferred(modelId, preferred) {
|
|
37853
|
+
return modelId === preferred || modelId.startsWith(`${preferred}-`);
|
|
37854
|
+
}
|
|
37855
|
+
function pickDefaultVisionModel(modelIds, current) {
|
|
37856
|
+
const visionModels = filterVisionModels(modelIds);
|
|
37857
|
+
if (visionModels.length === 0) return void 0;
|
|
37858
|
+
const trimmedCurrent = current?.trim();
|
|
37859
|
+
if (trimmedCurrent && visionModels.includes(trimmedCurrent)) {
|
|
37860
|
+
return trimmedCurrent;
|
|
37628
37861
|
}
|
|
37629
|
-
|
|
37630
|
-
|
|
37862
|
+
for (const preferred of PREFERRED_VISION_MODELS) {
|
|
37863
|
+
const match = visionModels.find((id) => matchesPreferred(id, preferred));
|
|
37864
|
+
if (match) return match;
|
|
37631
37865
|
}
|
|
37632
|
-
|
|
37633
|
-
|
|
37634
|
-
|
|
37635
|
-
|
|
37636
|
-
|
|
37637
|
-
|
|
37638
|
-
|
|
37639
|
-
|
|
37640
|
-
}));
|
|
37866
|
+
return visionModels[0];
|
|
37867
|
+
}
|
|
37868
|
+
|
|
37869
|
+
// src/common/aiApi/visionMessageFormats.ts
|
|
37870
|
+
function detectVisionMessageFormat(baseUrl) {
|
|
37871
|
+
const normalized = baseUrl.toLowerCase();
|
|
37872
|
+
if (normalized.includes("ollama") || normalized.includes(":11434") || normalized.includes("11434/")) {
|
|
37873
|
+
return "ollama";
|
|
37641
37874
|
}
|
|
37642
|
-
return
|
|
37643
|
-
}
|
|
37644
|
-
|
|
37645
|
-
return
|
|
37646
|
-
|
|
37647
|
-
|
|
37648
|
-
|
|
37649
|
-
|
|
37650
|
-
|
|
37651
|
-
|
|
37652
|
-
|
|
37653
|
-
|
|
37654
|
-
}
|
|
37655
|
-
|
|
37656
|
-
|
|
37657
|
-
|
|
37658
|
-
|
|
37659
|
-
|
|
37660
|
-
|
|
37661
|
-
|
|
37662
|
-
|
|
37663
|
-
|
|
37664
|
-
|
|
37665
|
-
|
|
37666
|
-
|
|
37667
|
-
|
|
37668
|
-
|
|
37669
|
-
|
|
37875
|
+
return "openai";
|
|
37876
|
+
}
|
|
37877
|
+
function assertVisionCapableModel(modelId, options) {
|
|
37878
|
+
if (!options?.hasImages) return;
|
|
37879
|
+
const model = modelId.trim();
|
|
37880
|
+
if (!model) {
|
|
37881
|
+
throw new Error("\u8BC6\u56FE\u9700\u8981\u9009\u62E9\u89C6\u89C9\u6A21\u578B\uFF0C\u8BF7\u5728 AI \u8BBE\u7F6E\u4E2D\u914D\u7F6E");
|
|
37882
|
+
}
|
|
37883
|
+
const format = options.baseUrl ? detectVisionMessageFormat(options.baseUrl) : "openai";
|
|
37884
|
+
if (format === "ollama") return;
|
|
37885
|
+
if (isKnownTextOnlyModel(model)) {
|
|
37886
|
+
throw new Error(
|
|
37887
|
+
`\u5F53\u524D\u6A21\u578B\u300C${model}\u300D\u4E0D\u652F\u6301\u56FE\u7247\u8F93\u5165\u3002\u8BF7\u6539\u7528\u89C6\u89C9\u6A21\u578B\uFF0C\u4F8B\u5982 gpt-4o-mini\u3001qwen-vl-max\u3001gemini-1.5-flash\u3001deepseek-vl \u7B49\uFF08DeepSeek \u6587\u672C\u6A21\u578B\u65E0\u6CD5\u8BC6\u56FE\uFF09\u3002`
|
|
37888
|
+
);
|
|
37889
|
+
}
|
|
37890
|
+
if (!isLikelyVisionModel(model)) {
|
|
37891
|
+
throw new Error(
|
|
37892
|
+
`\u6A21\u578B\u300C${model}\u300D\u53EF\u80FD\u4E0D\u652F\u6301\u56FE\u7247\u8BC6\u56FE\u3002\u8BF7\u5728 AI \u8BBE\u7F6E\u4E2D\u9009\u62E9\u540D\u79F0\u542B vl\u3001vision\u3001gpt-4o\u3001gemini \u7B49\u6807\u8BC6\u7684\u89C6\u89C9\u6A21\u578B\u3002`
|
|
37893
|
+
);
|
|
37894
|
+
}
|
|
37895
|
+
}
|
|
37896
|
+
function isImageUrlVariantError(message) {
|
|
37897
|
+
return /unknown variant [`']?image_url[`']?/i.test(message) || /expected [`']?text[`']?/i.test(message) || /does not support.*image/i.test(message);
|
|
37898
|
+
}
|
|
37899
|
+
function toVisionApiErrorMessage(rawMessage, modelId) {
|
|
37900
|
+
if (isImageUrlVariantError(rawMessage)) {
|
|
37901
|
+
return `\u5F53\u524D\u6A21\u578B\u300C${modelId}\u300D\u4E0D\u63A5\u53D7\u56FE\u7247\u8BF7\u6C42\uFF08${rawMessage}\uFF09\u3002\u8BF7\u66F4\u6362\u4E3A\u652F\u6301\u8BC6\u56FE\u7684\u89C6\u89C9\u6A21\u578B\u3002`;
|
|
37902
|
+
}
|
|
37903
|
+
return rawMessage;
|
|
37904
|
+
}
|
|
37905
|
+
|
|
37906
|
+
// src/common/aiApi/audioStrategy.ts
|
|
37907
|
+
function resolveAudioHandling(options) {
|
|
37908
|
+
if (!options.hasAudio) {
|
|
37909
|
+
return "none";
|
|
37910
|
+
}
|
|
37911
|
+
if (options.strategy === "stt") {
|
|
37912
|
+
return "stt";
|
|
37913
|
+
}
|
|
37914
|
+
if (options.strategy === "native") {
|
|
37915
|
+
return "native";
|
|
37916
|
+
}
|
|
37917
|
+
if (detectVisionMessageFormat(options.baseUrl) === "ollama") {
|
|
37918
|
+
return "stt";
|
|
37919
|
+
}
|
|
37920
|
+
if (isLikelyNativeAudioChatModel(options.model)) {
|
|
37921
|
+
return "native";
|
|
37922
|
+
}
|
|
37923
|
+
return "stt";
|
|
37924
|
+
}
|
|
37925
|
+
function isAudioInputError(message) {
|
|
37926
|
+
return /input_audio/i.test(message) || /unknown variant [`']?input_audio[`']?/i.test(message) || /does not support.*audio/i.test(message) || /audio input/i.test(message) || /invalid audio/i.test(message);
|
|
37927
|
+
}
|
|
37928
|
+
function appendTranscriptionsToPrompt(userPrompt, transcriptions) {
|
|
37929
|
+
if (transcriptions.length === 0) {
|
|
37930
|
+
return userPrompt;
|
|
37931
|
+
}
|
|
37932
|
+
const blocks = transcriptions.map((text3, index2) => {
|
|
37933
|
+
const label = transcriptions.length === 1 ? "[\u8BED\u97F3\u8F6C\u5199]" : `[\u8BED\u97F3\u8F6C\u5199 ${index2 + 1}]`;
|
|
37934
|
+
return `${label}
|
|
37935
|
+
${text3.trim()}`;
|
|
37936
|
+
});
|
|
37937
|
+
const joined = blocks.join("\n\n");
|
|
37938
|
+
const trimmedPrompt = userPrompt.trim();
|
|
37939
|
+
return trimmedPrompt ? `${trimmedPrompt}
|
|
37940
|
+
|
|
37941
|
+
${joined}` : joined;
|
|
37942
|
+
}
|
|
37943
|
+
|
|
37944
|
+
// src/common/aiApi/audioUtils.ts
|
|
37945
|
+
var ALLOWED_MIME = /* @__PURE__ */ new Set([
|
|
37946
|
+
"audio/wav",
|
|
37947
|
+
"audio/x-wav",
|
|
37948
|
+
"audio/mpeg",
|
|
37949
|
+
"audio/mp3",
|
|
37950
|
+
"audio/mp4",
|
|
37951
|
+
"audio/webm",
|
|
37952
|
+
"audio/ogg",
|
|
37953
|
+
"audio/flac"
|
|
37954
|
+
]);
|
|
37955
|
+
var MIME_TO_FORMAT = {
|
|
37956
|
+
"audio/wav": "wav",
|
|
37957
|
+
"audio/x-wav": "wav",
|
|
37958
|
+
"audio/mpeg": "mp3",
|
|
37959
|
+
"audio/mp3": "mp3",
|
|
37960
|
+
"audio/mp4": "mp4",
|
|
37961
|
+
"audio/webm": "webm",
|
|
37962
|
+
"audio/ogg": "ogg",
|
|
37963
|
+
"audio/flac": "flac"
|
|
37964
|
+
};
|
|
37965
|
+
function mimeToAudioFormat(mimeType) {
|
|
37966
|
+
return MIME_TO_FORMAT[mimeType] ?? mimeType.split("/").pop() ?? "wav";
|
|
37967
|
+
}
|
|
37968
|
+
function assertValidAudioInput(audio, maxAudioBytes = 25 * 1024 * 1024) {
|
|
37969
|
+
if (!audio.base64?.trim()) {
|
|
37970
|
+
throw new Error("\u97F3\u9891\u6570\u636E\u4E0D\u80FD\u4E3A\u7A7A");
|
|
37971
|
+
}
|
|
37972
|
+
if (!ALLOWED_MIME.has(audio.mimeType)) {
|
|
37973
|
+
throw new Error(`\u4E0D\u652F\u6301\u7684\u97F3\u9891\u683C\u5F0F: ${audio.mimeType}`);
|
|
37974
|
+
}
|
|
37975
|
+
const byteLength = estimateBase64ByteLength(audio.base64);
|
|
37976
|
+
if (byteLength > maxAudioBytes) {
|
|
37977
|
+
throw new Error(`\u97F3\u9891\u8FC7\u5927\uFF0C\u6700\u5927 ${Math.round(maxAudioBytes / 1024 / 1024)}MB`);
|
|
37978
|
+
}
|
|
37979
|
+
}
|
|
37980
|
+
function estimateBase64ByteLength(base64) {
|
|
37981
|
+
if (typeof Buffer !== "undefined") {
|
|
37982
|
+
return Buffer.byteLength(base64, "base64");
|
|
37983
|
+
}
|
|
37984
|
+
const padding = base64.endsWith("==") ? 2 : base64.endsWith("=") ? 1 : 0;
|
|
37985
|
+
return Math.floor(base64.length * 3 / 4) - padding;
|
|
37986
|
+
}
|
|
37987
|
+
async function fileToAiAudioInput(file) {
|
|
37988
|
+
const buffer = await file.arrayBuffer();
|
|
37989
|
+
if (typeof Buffer !== "undefined") {
|
|
37990
|
+
return {
|
|
37991
|
+
base64: Buffer.from(buffer).toString("base64"),
|
|
37992
|
+
mimeType: file.type || "audio/wav"
|
|
37993
|
+
};
|
|
37994
|
+
}
|
|
37995
|
+
const bytes = new Uint8Array(buffer);
|
|
37996
|
+
let binary = "";
|
|
37997
|
+
for (let index2 = 0; index2 < bytes.length; index2 += 1) {
|
|
37998
|
+
binary += String.fromCharCode(bytes[index2]);
|
|
37999
|
+
}
|
|
38000
|
+
return { base64: btoa(binary), mimeType: file.type || "audio/wav" };
|
|
38001
|
+
}
|
|
38002
|
+
function base64ToBlob(base64, mimeType) {
|
|
38003
|
+
if (typeof Buffer !== "undefined") {
|
|
38004
|
+
const bytes2 = Buffer.from(base64, "base64");
|
|
38005
|
+
return new Blob([bytes2], { type: mimeType });
|
|
38006
|
+
}
|
|
38007
|
+
const binary = atob(base64);
|
|
38008
|
+
const bytes = new Uint8Array(binary.length);
|
|
38009
|
+
for (let index2 = 0; index2 < binary.length; index2 += 1) {
|
|
38010
|
+
bytes[index2] = binary.charCodeAt(index2);
|
|
38011
|
+
}
|
|
38012
|
+
return new Blob([bytes], { type: mimeType });
|
|
38013
|
+
}
|
|
38014
|
+
|
|
38015
|
+
// src/common/aiApi/multimodalMessageFormats.ts
|
|
38016
|
+
function buildMultimodalMessages(options) {
|
|
38017
|
+
const { systemPrompt, userPrompt, images, nativeAudios, format } = options;
|
|
38018
|
+
const hasImages = images.length > 0;
|
|
38019
|
+
const hasNativeAudio = nativeAudios.length > 0;
|
|
38020
|
+
if (format === "ollama" && hasImages) {
|
|
38021
|
+
return [
|
|
38022
|
+
{ role: "system", content: systemPrompt },
|
|
38023
|
+
{
|
|
38024
|
+
role: "user",
|
|
38025
|
+
content: userPrompt,
|
|
38026
|
+
images: images.map((image) => image.base64)
|
|
37670
38027
|
}
|
|
37671
|
-
|
|
37672
|
-
|
|
38028
|
+
];
|
|
38029
|
+
}
|
|
38030
|
+
const userContent = [{ type: "text", text: userPrompt }];
|
|
38031
|
+
for (const image of images) {
|
|
38032
|
+
userContent.push({
|
|
38033
|
+
type: "image_url",
|
|
38034
|
+
image_url: {
|
|
38035
|
+
url: `data:${image.mimeType};base64,${image.base64}`
|
|
37673
38036
|
}
|
|
37674
|
-
|
|
37675
|
-
|
|
38037
|
+
});
|
|
38038
|
+
}
|
|
38039
|
+
for (const audio of nativeAudios) {
|
|
38040
|
+
userContent.push({
|
|
38041
|
+
type: "input_audio",
|
|
38042
|
+
input_audio: {
|
|
38043
|
+
data: audio.base64,
|
|
38044
|
+
format: mimeToAudioFormat(audio.mimeType)
|
|
37676
38045
|
}
|
|
37677
|
-
|
|
37678
|
-
|
|
37679
|
-
|
|
37680
|
-
|
|
37681
|
-
|
|
37682
|
-
|
|
37683
|
-
|
|
37684
|
-
|
|
37685
|
-
|
|
37686
|
-
|
|
37687
|
-
|
|
37688
|
-
|
|
37689
|
-
|
|
37690
|
-
|
|
37691
|
-
|
|
37692
|
-
|
|
37693
|
-
|
|
37694
|
-
|
|
37695
|
-
|
|
37696
|
-
content,
|
|
37697
|
-
message: assistantMessage,
|
|
37698
|
-
usage: normalizeUsage(response.usage),
|
|
37699
|
-
toolCalls,
|
|
37700
|
-
raw: response
|
|
37701
|
-
};
|
|
37702
|
-
}
|
|
37703
|
-
};
|
|
37704
|
-
};
|
|
38046
|
+
});
|
|
38047
|
+
}
|
|
38048
|
+
const useStructuredContent = hasImages || hasNativeAudio;
|
|
38049
|
+
return [
|
|
38050
|
+
{ role: "system", content: systemPrompt },
|
|
38051
|
+
{ role: "user", content: useStructuredContent ? userContent : userPrompt }
|
|
38052
|
+
];
|
|
38053
|
+
}
|
|
38054
|
+
function assertMultimodalCapableModel(modelId, options) {
|
|
38055
|
+
assertVisionCapableModel(modelId, {
|
|
38056
|
+
baseUrl: options.baseUrl,
|
|
38057
|
+
hasImages: options.hasImages
|
|
38058
|
+
});
|
|
38059
|
+
if (!options.hasNativeAudio) return;
|
|
38060
|
+
const format = options.baseUrl ? detectVisionMessageFormat(options.baseUrl) : "openai";
|
|
38061
|
+
if (format === "ollama") {
|
|
38062
|
+
throw new Error('\u5F53\u524D Ollama \u8FDE\u63A5\u4E0D\u652F\u6301 chat \u5185\u5D4C\u97F3\u9891\uFF0C\u8BF7\u6539\u7528 audioStrategy: "stt" \u6216 "auto"');
|
|
38063
|
+
}
|
|
38064
|
+
}
|
|
37705
38065
|
|
|
37706
|
-
// src/common/
|
|
37707
|
-
var
|
|
37708
|
-
|
|
37709
|
-
if (
|
|
37710
|
-
|
|
38066
|
+
// src/common/aiApi/imageUtils.ts
|
|
38067
|
+
var ALLOWED_MIME2 = /* @__PURE__ */ new Set(["image/jpeg", "image/png", "image/webp", "image/gif"]);
|
|
38068
|
+
function assertValidImageInput(image, maxImageBytes = 5 * 1024 * 1024) {
|
|
38069
|
+
if (!image.base64?.trim()) {
|
|
38070
|
+
throw new Error("\u56FE\u7247\u6570\u636E\u4E0D\u80FD\u4E3A\u7A7A");
|
|
37711
38071
|
}
|
|
37712
|
-
if (
|
|
37713
|
-
|
|
38072
|
+
if (!ALLOWED_MIME2.has(image.mimeType)) {
|
|
38073
|
+
throw new Error(`\u4E0D\u652F\u6301\u7684\u56FE\u7247\u683C\u5F0F: ${image.mimeType}`);
|
|
37714
38074
|
}
|
|
37715
|
-
|
|
37716
|
-
|
|
37717
|
-
|
|
37718
|
-
|
|
37719
|
-
}
|
|
37720
|
-
|
|
37721
|
-
|
|
37722
|
-
|
|
37723
|
-
|
|
37724
|
-
|
|
37725
|
-
|
|
37726
|
-
|
|
37727
|
-
|
|
37728
|
-
|
|
38075
|
+
const byteLength = estimateBase64ByteLength2(image.base64);
|
|
38076
|
+
if (byteLength > maxImageBytes) {
|
|
38077
|
+
throw new Error(`\u56FE\u7247\u8FC7\u5927\uFF0C\u6700\u5927 ${Math.round(maxImageBytes / 1024 / 1024)}MB`);
|
|
38078
|
+
}
|
|
38079
|
+
}
|
|
38080
|
+
function estimateBase64ByteLength2(base64) {
|
|
38081
|
+
if (typeof Buffer !== "undefined") {
|
|
38082
|
+
return Buffer.byteLength(base64, "base64");
|
|
38083
|
+
}
|
|
38084
|
+
const padding = base64.endsWith("==") ? 2 : base64.endsWith("=") ? 1 : 0;
|
|
38085
|
+
return Math.floor(base64.length * 3 / 4) - padding;
|
|
38086
|
+
}
|
|
38087
|
+
async function fileToAiImageInput(file) {
|
|
38088
|
+
const buffer = await file.arrayBuffer();
|
|
38089
|
+
if (typeof Buffer !== "undefined") {
|
|
38090
|
+
return {
|
|
38091
|
+
base64: Buffer.from(buffer).toString("base64"),
|
|
38092
|
+
mimeType: file.type || "image/jpeg"
|
|
38093
|
+
};
|
|
38094
|
+
}
|
|
38095
|
+
const bytes = new Uint8Array(buffer);
|
|
38096
|
+
let binary = "";
|
|
38097
|
+
for (let index2 = 0; index2 < bytes.length; index2 += 1) {
|
|
38098
|
+
binary += String.fromCharCode(bytes[index2]);
|
|
38099
|
+
}
|
|
38100
|
+
const base64 = btoa(binary);
|
|
38101
|
+
return { base64, mimeType: file.type || "image/jpeg" };
|
|
38102
|
+
}
|
|
38103
|
+
|
|
38104
|
+
// src/common/aiApi/mediaUtils.ts
|
|
38105
|
+
function splitMediaByKind(media) {
|
|
38106
|
+
const images = [];
|
|
38107
|
+
const audios = [];
|
|
38108
|
+
for (const item of media) {
|
|
38109
|
+
if (item.kind === "image") {
|
|
38110
|
+
images.push(item);
|
|
38111
|
+
} else {
|
|
38112
|
+
audios.push(item);
|
|
37729
38113
|
}
|
|
37730
38114
|
}
|
|
37731
|
-
return
|
|
37732
|
-
}
|
|
37733
|
-
|
|
37734
|
-
const
|
|
37735
|
-
|
|
37736
|
-
|
|
37737
|
-
|
|
37738
|
-
|
|
37739
|
-
|
|
37740
|
-
}
|
|
37741
|
-
|
|
37742
|
-
|
|
37743
|
-
|
|
37744
|
-
|
|
37745
|
-
|
|
37746
|
-
|
|
37747
|
-
|
|
37748
|
-
|
|
37749
|
-
|
|
37750
|
-
|
|
37751
|
-
|
|
38115
|
+
return { images, audios };
|
|
38116
|
+
}
|
|
38117
|
+
function assertValidMultimodalMedia(media, limits) {
|
|
38118
|
+
const items = media ?? [];
|
|
38119
|
+
const { images, audios } = splitMediaByKind(items);
|
|
38120
|
+
const maxImages = limits.maxImages ?? 8;
|
|
38121
|
+
const maxAudios = limits.maxAudios ?? 4;
|
|
38122
|
+
if (images.length > maxImages) {
|
|
38123
|
+
throw new Error(`\u56FE\u7247\u6570\u91CF\u8FC7\u591A\uFF0C\u6700\u591A ${maxImages} \u5F20`);
|
|
38124
|
+
}
|
|
38125
|
+
if (audios.length > maxAudios) {
|
|
38126
|
+
throw new Error(`\u97F3\u9891\u6570\u91CF\u8FC7\u591A\uFF0C\u6700\u591A ${maxAudios} \u6BB5`);
|
|
38127
|
+
}
|
|
38128
|
+
for (const image of images) {
|
|
38129
|
+
assertValidImageInput(
|
|
38130
|
+
{ base64: image.base64, mimeType: image.mimeType },
|
|
38131
|
+
limits.maxImageBytes
|
|
38132
|
+
);
|
|
38133
|
+
}
|
|
38134
|
+
for (const audio of audios) {
|
|
38135
|
+
assertValidAudioInput(
|
|
38136
|
+
{ base64: audio.base64, mimeType: audio.mimeType },
|
|
38137
|
+
limits.maxAudioBytes
|
|
38138
|
+
);
|
|
38139
|
+
}
|
|
38140
|
+
return items;
|
|
38141
|
+
}
|
|
38142
|
+
|
|
38143
|
+
// src/common/aiApi/transcribeAudio.ts
|
|
38144
|
+
function joinUrl2(baseUrl, path) {
|
|
38145
|
+
return `${baseUrl.replace(/\/+$/, "")}/${path.replace(/^\/+/, "")}`;
|
|
38146
|
+
}
|
|
38147
|
+
async function transcribeAudio(options) {
|
|
38148
|
+
const { audio, config, model, language } = options;
|
|
38149
|
+
const sttModel = model?.trim() || config.audioModel;
|
|
38150
|
+
const blob = base64ToBlob(audio.base64, audio.mimeType);
|
|
38151
|
+
const extension = mimeToAudioFormat(audio.mimeType);
|
|
38152
|
+
const form = new FormData();
|
|
38153
|
+
form.append("file", blob, `audio.${extension}`);
|
|
38154
|
+
form.append("model", sttModel);
|
|
38155
|
+
if (language?.trim()) {
|
|
38156
|
+
form.append("language", language.trim());
|
|
38157
|
+
}
|
|
38158
|
+
const controller = new AbortController();
|
|
38159
|
+
const timeoutId = setTimeout(() => controller.abort(), config.timeoutMs);
|
|
38160
|
+
try {
|
|
38161
|
+
const response = await fetch(joinUrl2(config.baseUrl, "audio/transcriptions"), {
|
|
38162
|
+
method: "POST",
|
|
38163
|
+
headers: {
|
|
38164
|
+
Authorization: `Bearer ${config.apiKey}`
|
|
38165
|
+
},
|
|
38166
|
+
body: form,
|
|
38167
|
+
signal: controller.signal
|
|
37752
38168
|
});
|
|
37753
|
-
|
|
37754
|
-
|
|
37755
|
-
|
|
37756
|
-
|
|
37757
|
-
|
|
38169
|
+
const text3 = await response.text();
|
|
38170
|
+
let data = null;
|
|
38171
|
+
if (text3) {
|
|
38172
|
+
try {
|
|
38173
|
+
data = JSON.parse(text3);
|
|
38174
|
+
} catch {
|
|
38175
|
+
data = text3;
|
|
38176
|
+
}
|
|
37758
38177
|
}
|
|
37759
|
-
|
|
37760
|
-
|
|
37761
|
-
|
|
37762
|
-
|
|
37763
|
-
const messages = [];
|
|
37764
|
-
if (systemPrompt) {
|
|
37765
|
-
messages.push({ role: "system", content: systemPrompt });
|
|
38178
|
+
if (!response.ok) {
|
|
38179
|
+
const record = data;
|
|
38180
|
+
const errorMessage2 = (typeof record?.error === "object" ? record.error?.message : record?.error) || record?.message || `STT \u8BF7\u6C42\u5931\u8D25 (${response.status})`;
|
|
38181
|
+
throw new Error(String(errorMessage2));
|
|
37766
38182
|
}
|
|
37767
|
-
|
|
37768
|
-
|
|
37769
|
-
|
|
37770
|
-
|
|
37771
|
-
|
|
38183
|
+
if (typeof data === "string") {
|
|
38184
|
+
return data.trim();
|
|
38185
|
+
}
|
|
38186
|
+
const parsed = data;
|
|
38187
|
+
return (parsed.text ?? "").trim();
|
|
38188
|
+
} finally {
|
|
38189
|
+
clearTimeout(timeoutId);
|
|
38190
|
+
}
|
|
38191
|
+
}
|
|
38192
|
+
async function transcribeAudios(audios, config, model) {
|
|
38193
|
+
const results = [];
|
|
38194
|
+
for (const audio of audios) {
|
|
38195
|
+
results.push(await transcribeAudio({ audio, config, model }));
|
|
38196
|
+
}
|
|
38197
|
+
return results;
|
|
38198
|
+
}
|
|
38199
|
+
|
|
38200
|
+
// src/common/aiApi/callMultimodalChat.ts
|
|
38201
|
+
function joinUrl3(baseUrl, path) {
|
|
38202
|
+
return `${baseUrl.replace(/\/+$/, "")}/${path.replace(/^\/+/, "")}`;
|
|
38203
|
+
}
|
|
38204
|
+
async function requestMultimodalChat(options) {
|
|
38205
|
+
const payload = {
|
|
38206
|
+
model: options.model,
|
|
38207
|
+
messages: options.messages,
|
|
38208
|
+
temperature: options.temperature ?? 0.2
|
|
37772
38209
|
};
|
|
38210
|
+
if (options.maxTokens !== void 0) {
|
|
38211
|
+
payload.max_tokens = options.maxTokens;
|
|
38212
|
+
}
|
|
38213
|
+
if (options.jsonMode) {
|
|
38214
|
+
payload.response_format = { type: "json_object" };
|
|
38215
|
+
}
|
|
38216
|
+
const raw = await requestJson({
|
|
38217
|
+
url: joinUrl3(options.config.baseUrl, "chat/completions"),
|
|
38218
|
+
method: "POST",
|
|
38219
|
+
headers: {
|
|
38220
|
+
"Content-Type": "application/json",
|
|
38221
|
+
Authorization: `Bearer ${options.config.apiKey}`
|
|
38222
|
+
},
|
|
38223
|
+
body: payload,
|
|
38224
|
+
timeoutMs: options.config.timeoutMs
|
|
38225
|
+
});
|
|
37773
38226
|
return {
|
|
37774
|
-
|
|
37775
|
-
|
|
38227
|
+
content: raw.choices?.[0]?.message?.content ?? "",
|
|
38228
|
+
model: raw.model ?? options.model,
|
|
38229
|
+
raw
|
|
37776
38230
|
};
|
|
37777
|
-
}
|
|
37778
|
-
|
|
37779
|
-
|
|
37780
|
-
|
|
37781
|
-
|
|
37782
|
-
|
|
37783
|
-
|
|
37784
|
-
|
|
37785
|
-
|
|
37786
|
-
normalized[key] = String(value);
|
|
37787
|
-
}
|
|
38231
|
+
}
|
|
38232
|
+
function toAudioInputs(audios) {
|
|
38233
|
+
return audios.map((audio) => ({ base64: audio.base64, mimeType: audio.mimeType }));
|
|
38234
|
+
}
|
|
38235
|
+
async function callMultimodalChat(params, clientSettings) {
|
|
38236
|
+
const config = requireAiConnectionConfig(params.connection, clientSettings);
|
|
38237
|
+
const media = assertValidMultimodalMedia(params.media, {
|
|
38238
|
+
maxImageBytes: config.maxImageBytes,
|
|
38239
|
+
maxAudioBytes: config.maxAudioBytes
|
|
37788
38240
|
});
|
|
37789
|
-
|
|
37790
|
-
|
|
38241
|
+
const { images, audios } = splitMediaByKind(media);
|
|
38242
|
+
const hasImages = images.length > 0;
|
|
38243
|
+
const hasAudio = audios.length > 0;
|
|
38244
|
+
const model = params.model || (hasImages ? config.visionModel : hasAudio ? config.visionModel : config.textModel);
|
|
38245
|
+
const strategy = params.audioStrategy ?? config.audioStrategy;
|
|
38246
|
+
const format = detectVisionMessageFormat(config.baseUrl);
|
|
38247
|
+
let audioHandling = resolveAudioHandling({
|
|
38248
|
+
hasAudio,
|
|
38249
|
+
strategy,
|
|
38250
|
+
model,
|
|
38251
|
+
baseUrl: config.baseUrl
|
|
38252
|
+
});
|
|
38253
|
+
let userPrompt = params.userPrompt;
|
|
38254
|
+
let transcriptions;
|
|
38255
|
+
let nativeAudios = [];
|
|
38256
|
+
if (audioHandling === "stt" && hasAudio) {
|
|
38257
|
+
transcriptions = await transcribeAudios(toAudioInputs(audios), config);
|
|
38258
|
+
userPrompt = appendTranscriptionsToPrompt(userPrompt, transcriptions);
|
|
38259
|
+
} else if (audioHandling === "native" && hasAudio) {
|
|
38260
|
+
nativeAudios = audios;
|
|
38261
|
+
}
|
|
38262
|
+
assertMultimodalCapableModel(model, {
|
|
38263
|
+
baseUrl: config.baseUrl,
|
|
38264
|
+
hasImages,
|
|
38265
|
+
hasNativeAudio: nativeAudios.length > 0
|
|
38266
|
+
});
|
|
38267
|
+
const messages = buildMultimodalMessages({
|
|
38268
|
+
systemPrompt: params.systemPrompt,
|
|
38269
|
+
userPrompt,
|
|
38270
|
+
images,
|
|
38271
|
+
nativeAudios,
|
|
38272
|
+
format
|
|
38273
|
+
});
|
|
38274
|
+
try {
|
|
38275
|
+
const result = await requestMultimodalChat({
|
|
38276
|
+
config,
|
|
38277
|
+
model,
|
|
38278
|
+
messages,
|
|
38279
|
+
temperature: params.temperature,
|
|
38280
|
+
maxTokens: params.maxTokens,
|
|
38281
|
+
jsonMode: params.jsonMode
|
|
38282
|
+
});
|
|
38283
|
+
return {
|
|
38284
|
+
...result,
|
|
38285
|
+
audioHandling,
|
|
38286
|
+
transcriptions
|
|
38287
|
+
};
|
|
38288
|
+
} catch (error) {
|
|
38289
|
+
const message = error instanceof Error ? error.message : "AI \u8BF7\u6C42\u5931\u8D25";
|
|
38290
|
+
if (audioHandling === "native" && hasAudio && strategy === "auto" && isAudioInputError(message)) {
|
|
38291
|
+
transcriptions = await transcribeAudios(toAudioInputs(audios), config);
|
|
38292
|
+
userPrompt = appendTranscriptionsToPrompt(params.userPrompt, transcriptions);
|
|
38293
|
+
audioHandling = "stt";
|
|
38294
|
+
const fallbackMessages = buildMultimodalMessages({
|
|
38295
|
+
systemPrompt: params.systemPrompt,
|
|
38296
|
+
userPrompt,
|
|
38297
|
+
images,
|
|
38298
|
+
nativeAudios: [],
|
|
38299
|
+
format
|
|
38300
|
+
});
|
|
38301
|
+
const result = await requestMultimodalChat({
|
|
38302
|
+
config,
|
|
38303
|
+
model,
|
|
38304
|
+
messages: fallbackMessages,
|
|
38305
|
+
temperature: params.temperature,
|
|
38306
|
+
maxTokens: params.maxTokens,
|
|
38307
|
+
jsonMode: params.jsonMode
|
|
38308
|
+
});
|
|
38309
|
+
return {
|
|
38310
|
+
...result,
|
|
38311
|
+
audioHandling,
|
|
38312
|
+
transcriptions
|
|
38313
|
+
};
|
|
38314
|
+
}
|
|
38315
|
+
throw new Error(toVisionApiErrorMessage(message, model));
|
|
38316
|
+
}
|
|
38317
|
+
}
|
|
37791
38318
|
|
|
37792
|
-
// src/common/
|
|
37793
|
-
|
|
37794
|
-
|
|
37795
|
-
|
|
38319
|
+
// src/common/aiApi/jsonUtils.ts
|
|
38320
|
+
function extractJsonObject(text3) {
|
|
38321
|
+
const trimmed = text3.trim();
|
|
38322
|
+
if (!trimmed) {
|
|
38323
|
+
throw new Error("\u6A21\u578B\u8FD4\u56DE\u4E3A\u7A7A");
|
|
37796
38324
|
}
|
|
37797
|
-
|
|
37798
|
-
|
|
37799
|
-
|
|
37800
|
-
|
|
37801
|
-
return resolved[key] ?? "";
|
|
38325
|
+
try {
|
|
38326
|
+
const parsed = JSON.parse(trimmed);
|
|
38327
|
+
if (parsed && typeof parsed === "object" && !Array.isArray(parsed)) {
|
|
38328
|
+
return parsed;
|
|
37802
38329
|
}
|
|
37803
|
-
|
|
37804
|
-
});
|
|
37805
|
-
};
|
|
37806
|
-
|
|
37807
|
-
// src/common/ai/llm/client/createChatSession.ts
|
|
37808
|
-
var buildBaseMessages = (systemPrompt, initialMessages) => {
|
|
37809
|
-
const baseMessages = [];
|
|
37810
|
-
if (systemPrompt) {
|
|
37811
|
-
baseMessages.push({ role: "system", content: systemPrompt });
|
|
38330
|
+
} catch {
|
|
37812
38331
|
}
|
|
37813
|
-
|
|
37814
|
-
|
|
38332
|
+
const fenced = trimmed.match(/```(?:json)?\s*([\s\S]*?)```/i);
|
|
38333
|
+
if (fenced?.[1]) {
|
|
38334
|
+
const parsed = JSON.parse(fenced[1].trim());
|
|
38335
|
+
if (parsed && typeof parsed === "object" && !Array.isArray(parsed)) {
|
|
38336
|
+
return parsed;
|
|
38337
|
+
}
|
|
37815
38338
|
}
|
|
37816
|
-
|
|
37817
|
-
};
|
|
37818
|
-
|
|
37819
|
-
|
|
37820
|
-
|
|
37821
|
-
|
|
37822
|
-
|
|
37823
|
-
};
|
|
37824
|
-
const setSystemPrompt = (prompt2) => {
|
|
37825
|
-
systemPrompt = prompt2;
|
|
37826
|
-
reset();
|
|
37827
|
-
};
|
|
37828
|
-
const sendMessage = async (input, requestOptions = {}) => {
|
|
37829
|
-
const { template, variables, ...chatOptions } = requestOptions;
|
|
37830
|
-
const activeTemplate = template ?? options.template;
|
|
37831
|
-
const mergedVariables = { input, ...variables ?? {} };
|
|
37832
|
-
const content = activeTemplate ? applyPromptTemplate(activeTemplate, mergedVariables) : input;
|
|
37833
|
-
const userMessage = { role: "user", content };
|
|
37834
|
-
const nextMessages = [...messages, userMessage];
|
|
37835
|
-
const response = await options.client.sendChat({
|
|
37836
|
-
messages: nextMessages,
|
|
37837
|
-
...chatOptions
|
|
37838
|
-
});
|
|
37839
|
-
const assistantMessage = response.message ?? {
|
|
37840
|
-
role: "assistant",
|
|
37841
|
-
content: response.content,
|
|
37842
|
-
toolCalls: response.toolCalls
|
|
37843
|
-
};
|
|
37844
|
-
messages = [...nextMessages, assistantMessage];
|
|
37845
|
-
return response;
|
|
37846
|
-
};
|
|
37847
|
-
return {
|
|
37848
|
-
getMessages: () => messages,
|
|
37849
|
-
setSystemPrompt,
|
|
37850
|
-
reset,
|
|
37851
|
-
sendMessage
|
|
37852
|
-
};
|
|
37853
|
-
};
|
|
37854
|
-
var buildBaseMessages2 = (systemPrompt, initialMessages) => {
|
|
37855
|
-
const baseMessages = [];
|
|
37856
|
-
if (systemPrompt) {
|
|
37857
|
-
baseMessages.push({ role: "system", content: systemPrompt });
|
|
38339
|
+
const start = trimmed.indexOf("{");
|
|
38340
|
+
const end = trimmed.lastIndexOf("}");
|
|
38341
|
+
if (start >= 0 && end > start) {
|
|
38342
|
+
const parsed = JSON.parse(trimmed.slice(start, end + 1));
|
|
38343
|
+
if (parsed && typeof parsed === "object" && !Array.isArray(parsed)) {
|
|
38344
|
+
return parsed;
|
|
38345
|
+
}
|
|
37858
38346
|
}
|
|
37859
|
-
|
|
37860
|
-
|
|
38347
|
+
throw new Error("\u65E0\u6CD5\u89E3\u6790\u6A21\u578B JSON \u8F93\u51FA");
|
|
38348
|
+
}
|
|
38349
|
+
|
|
38350
|
+
// src/common/aiApi/listModels.ts
|
|
38351
|
+
function joinUrl4(baseUrl, path) {
|
|
38352
|
+
return `${baseUrl.replace(/\/+$/, "")}/${path.replace(/^\/+/, "")}`;
|
|
38353
|
+
}
|
|
38354
|
+
function parseModelIds(raw) {
|
|
38355
|
+
if (Array.isArray(raw.data)) {
|
|
38356
|
+
return raw.data.map((item) => item.id).filter((id) => Boolean(id));
|
|
37861
38357
|
}
|
|
37862
|
-
|
|
37863
|
-
|
|
37864
|
-
|
|
37865
|
-
|
|
37866
|
-
|
|
37867
|
-
|
|
37868
|
-
|
|
37869
|
-
)
|
|
37870
|
-
|
|
37871
|
-
|
|
37872
|
-
const
|
|
37873
|
-
|
|
37874
|
-
|
|
37875
|
-
|
|
37876
|
-
|
|
37877
|
-
};
|
|
37878
|
-
const reset = React107.useCallback(() => {
|
|
37879
|
-
syncMessages(buildBaseMessages2(systemPromptRef.current, options.initialMessages));
|
|
37880
|
-
setStatus("idle");
|
|
37881
|
-
setError(null);
|
|
37882
|
-
setLastResponse(null);
|
|
37883
|
-
}, [options.initialMessages]);
|
|
37884
|
-
const setSystemPrompt = React107.useCallback(
|
|
37885
|
-
(prompt2) => {
|
|
37886
|
-
systemPromptRef.current = prompt2;
|
|
37887
|
-
reset();
|
|
37888
|
-
},
|
|
37889
|
-
[reset]
|
|
37890
|
-
);
|
|
37891
|
-
const sendMessage = React107.useCallback(
|
|
37892
|
-
async (input, requestOptions = {}) => {
|
|
37893
|
-
const { template, variables, ...chatOptions } = requestOptions;
|
|
37894
|
-
const activeTemplate = template ?? templateRef.current;
|
|
37895
|
-
const mergedVariables = { input, ...variables ?? {} };
|
|
37896
|
-
const content = activeTemplate ? applyPromptTemplate(activeTemplate, mergedVariables) : input;
|
|
37897
|
-
const userMessage = { role: "user", content };
|
|
37898
|
-
const nextMessages = [...messagesRef.current, userMessage];
|
|
37899
|
-
syncMessages(nextMessages);
|
|
37900
|
-
setStatus("loading");
|
|
37901
|
-
setError(null);
|
|
37902
|
-
try {
|
|
37903
|
-
const response = await options.client.sendChat({
|
|
37904
|
-
messages: nextMessages,
|
|
37905
|
-
...chatOptions
|
|
37906
|
-
});
|
|
37907
|
-
const assistantMessage = response.message ?? {
|
|
37908
|
-
role: "assistant",
|
|
37909
|
-
content: response.content,
|
|
37910
|
-
toolCalls: response.toolCalls
|
|
37911
|
-
};
|
|
37912
|
-
const updatedMessages = [...nextMessages, assistantMessage];
|
|
37913
|
-
syncMessages(updatedMessages);
|
|
37914
|
-
setStatus("success");
|
|
37915
|
-
setLastResponse(response);
|
|
37916
|
-
return response;
|
|
37917
|
-
} catch (err) {
|
|
37918
|
-
const nextError = err instanceof Error ? err : new Error(String(err));
|
|
37919
|
-
setStatus("error");
|
|
37920
|
-
setError(nextError);
|
|
37921
|
-
throw nextError;
|
|
37922
|
-
}
|
|
38358
|
+
if (Array.isArray(raw.models)) {
|
|
38359
|
+
return raw.models.map((item) => typeof item === "string" ? item : item.id).filter((id) => Boolean(id));
|
|
38360
|
+
}
|
|
38361
|
+
return [];
|
|
38362
|
+
}
|
|
38363
|
+
async function listOpenAiCompatibleModels(clientSettings, currentVisionModel) {
|
|
38364
|
+
const config = resolveAiConnectionConfig(clientSettings);
|
|
38365
|
+
if (!config) {
|
|
38366
|
+
throw new Error("\u672A\u914D\u7F6E AI API Key\uFF0C\u8BF7\u5728\u8BBE\u7F6E\u4E2D\u586B\u5199\u6216\u914D\u7F6E\u670D\u52A1\u7AEF\u73AF\u5883\u53D8\u91CF");
|
|
38367
|
+
}
|
|
38368
|
+
const raw = await requestJson({
|
|
38369
|
+
url: joinUrl4(config.baseUrl, "models"),
|
|
38370
|
+
method: "GET",
|
|
38371
|
+
headers: {
|
|
38372
|
+
Authorization: `Bearer ${config.apiKey}`
|
|
37923
38373
|
},
|
|
37924
|
-
|
|
37925
|
-
);
|
|
37926
|
-
|
|
37927
|
-
|
|
37928
|
-
|
|
37929
|
-
|
|
37930
|
-
|
|
37931
|
-
|
|
37932
|
-
|
|
37933
|
-
|
|
37934
|
-
|
|
37935
|
-
};
|
|
37936
|
-
};
|
|
38374
|
+
timeoutMs: config.timeoutMs
|
|
38375
|
+
});
|
|
38376
|
+
const modelIds = parseModelIds(raw);
|
|
38377
|
+
if (modelIds.length === 0) {
|
|
38378
|
+
throw new Error("\u63A5\u53E3\u672A\u8FD4\u56DE\u53EF\u7528\u6A21\u578B");
|
|
38379
|
+
}
|
|
38380
|
+
const models = filterChatModels(modelIds);
|
|
38381
|
+
const visionModels = filterVisionModels(modelIds);
|
|
38382
|
+
const suggestedVisionModel = pickDefaultVisionModel(modelIds, currentVisionModel);
|
|
38383
|
+
return { models, visionModels, suggestedVisionModel };
|
|
38384
|
+
}
|
|
37937
38385
|
|
|
37938
|
-
// src/common/
|
|
37939
|
-
var
|
|
37940
|
-
|
|
37941
|
-
|
|
37942
|
-
|
|
37943
|
-
|
|
37944
|
-
description: skill.description
|
|
37945
|
-
}
|
|
37946
|
-
};
|
|
37947
|
-
if (skill.inputSchema) {
|
|
37948
|
-
toolDefinition.function.parameters = skill.inputSchema;
|
|
38386
|
+
// src/common/aiApi/taskRegistry.ts
|
|
38387
|
+
var registry2 = /* @__PURE__ */ new Map();
|
|
38388
|
+
function registerAiTask(task) {
|
|
38389
|
+
if (registry2.has(task.id)) {
|
|
38390
|
+
console.warn(`[aiApi] task "${task.id}" already registered, skipping duplicate`);
|
|
38391
|
+
return;
|
|
37949
38392
|
}
|
|
37950
|
-
|
|
37951
|
-
}
|
|
37952
|
-
|
|
37953
|
-
|
|
37954
|
-
|
|
37955
|
-
|
|
37956
|
-
|
|
37957
|
-
|
|
38393
|
+
registry2.set(task.id, task);
|
|
38394
|
+
}
|
|
38395
|
+
function getAiTask(taskId) {
|
|
38396
|
+
return registry2.get(taskId);
|
|
38397
|
+
}
|
|
38398
|
+
function listAiTasks() {
|
|
38399
|
+
return Array.from(registry2.keys());
|
|
38400
|
+
}
|
|
38401
|
+
function clearAiTasksForTest() {
|
|
38402
|
+
registry2.clear();
|
|
38403
|
+
}
|
|
38404
|
+
|
|
38405
|
+
// src/common/aiApi/runTask.ts
|
|
38406
|
+
function extractInputConnection(input) {
|
|
38407
|
+
if (!input || typeof input !== "object") return void 0;
|
|
38408
|
+
const connection = input.connection;
|
|
38409
|
+
return connection && typeof connection === "object" ? connection : void 0;
|
|
38410
|
+
}
|
|
38411
|
+
async function runAiTask(taskId, input, ctx = {}) {
|
|
38412
|
+
const started = Date.now();
|
|
38413
|
+
if (!resolveAiConnectionConfig(extractInputConnection(input), ctx.clientSettings)) {
|
|
38414
|
+
return {
|
|
38415
|
+
success: false,
|
|
38416
|
+
taskId,
|
|
38417
|
+
error: {
|
|
38418
|
+
code: "AI_CONFIG_MISSING",
|
|
38419
|
+
message: "\u672A\u914D\u7F6E AI API Key\uFF0C\u8BF7\u4F20\u5165 clientSettings.connection \u6216\u8BBE\u7F6E\u73AF\u5883\u53D8\u91CF AI_API_KEY"
|
|
38420
|
+
}
|
|
38421
|
+
};
|
|
38422
|
+
}
|
|
38423
|
+
const task = getAiTask(taskId);
|
|
38424
|
+
if (!task) {
|
|
38425
|
+
return {
|
|
38426
|
+
success: false,
|
|
38427
|
+
taskId,
|
|
38428
|
+
error: {
|
|
38429
|
+
code: "TASK_NOT_FOUND",
|
|
38430
|
+
message: `\u672A\u6CE8\u518C\u7684\u4EFB\u52A1: ${taskId}`
|
|
38431
|
+
}
|
|
38432
|
+
};
|
|
38433
|
+
}
|
|
38434
|
+
try {
|
|
38435
|
+
const validated = task.validateInput(input);
|
|
38436
|
+
const result = await task.execute(validated, ctx);
|
|
38437
|
+
return {
|
|
38438
|
+
success: true,
|
|
38439
|
+
taskId,
|
|
38440
|
+
data: result.data,
|
|
38441
|
+
meta: {
|
|
38442
|
+
model: result.meta?.model ?? "unknown",
|
|
38443
|
+
latencyMs: Date.now() - started,
|
|
38444
|
+
provider: result.meta?.provider ?? "openai-compatible",
|
|
38445
|
+
confidence: result.meta?.confidence,
|
|
38446
|
+
rawSummary: result.meta?.rawSummary
|
|
38447
|
+
}
|
|
38448
|
+
};
|
|
38449
|
+
} catch (error) {
|
|
38450
|
+
const message = error instanceof Error ? error.message : "AI \u4EFB\u52A1\u6267\u884C\u5931\u8D25";
|
|
38451
|
+
const code = classifyError(message);
|
|
38452
|
+
return {
|
|
38453
|
+
success: false,
|
|
38454
|
+
taskId,
|
|
38455
|
+
error: { code, message },
|
|
38456
|
+
meta: {
|
|
38457
|
+
model: "unknown",
|
|
38458
|
+
latencyMs: Date.now() - started
|
|
38459
|
+
}
|
|
38460
|
+
};
|
|
37958
38461
|
}
|
|
37959
|
-
|
|
37960
|
-
|
|
38462
|
+
}
|
|
38463
|
+
function classifyError(message) {
|
|
38464
|
+
if (message.includes("\u672A\u914D\u7F6E") || message.includes("AI_API_KEY") || message.includes("apiKey")) {
|
|
38465
|
+
return "AI_CONFIG_MISSING";
|
|
37961
38466
|
}
|
|
37962
|
-
|
|
37963
|
-
return
|
|
38467
|
+
if (message.includes("\u56FE\u7247") || message.includes("\u683C\u5F0F")) {
|
|
38468
|
+
return message.includes("\u8FC7\u5927") ? "PAYLOAD_TOO_LARGE" : "UNSUPPORTED_MEDIA";
|
|
37964
38469
|
}
|
|
37965
|
-
|
|
37966
|
-
return
|
|
38470
|
+
if (message.includes("\u89E3\u6790") || message.includes("JSON")) {
|
|
38471
|
+
return "AI_PARSE_FAILED";
|
|
37967
38472
|
}
|
|
37968
|
-
|
|
37969
|
-
return
|
|
38473
|
+
if (message.includes("\u5FC5\u586B") || message.includes("\u65E0\u6548")) {
|
|
38474
|
+
return "INVALID_INPUT";
|
|
37970
38475
|
}
|
|
37971
|
-
|
|
37972
|
-
|
|
37973
|
-
|
|
37974
|
-
|
|
38476
|
+
return "AI_REQUEST_FAILED";
|
|
38477
|
+
}
|
|
38478
|
+
|
|
38479
|
+
// src/common/aiApi/tasks/coreLlmCompletion.ts
|
|
38480
|
+
function isTextCompletionInput(input) {
|
|
38481
|
+
if (!input || typeof input !== "object") return false;
|
|
38482
|
+
const value = input;
|
|
38483
|
+
return typeof value.userPrompt === "string" && value.userPrompt.trim().length > 0;
|
|
38484
|
+
}
|
|
38485
|
+
var coreLlmCompletionTask = {
|
|
38486
|
+
id: CORE_LLM_COMPLETION_TASK_ID,
|
|
38487
|
+
description: "\u901A\u7528\u6587\u672C\u8865\u5168\uFF1Asystem/user \u63D0\u793A\u8BCD \u2192 \u6A21\u578B\u6587\u672C",
|
|
38488
|
+
validateInput(input) {
|
|
38489
|
+
if (!isTextCompletionInput(input)) {
|
|
38490
|
+
throw new Error("userPrompt \u4E3A\u5FC5\u586B");
|
|
37975
38491
|
}
|
|
37976
|
-
return
|
|
38492
|
+
return input;
|
|
38493
|
+
},
|
|
38494
|
+
async execute(input, ctx) {
|
|
38495
|
+
const result = await callCompletion(
|
|
38496
|
+
{
|
|
38497
|
+
systemPrompt: input.systemPrompt,
|
|
38498
|
+
userPrompt: input.userPrompt,
|
|
38499
|
+
model: input.model,
|
|
38500
|
+
temperature: input.temperature,
|
|
38501
|
+
maxTokens: input.maxTokens,
|
|
38502
|
+
connection: input.connection
|
|
38503
|
+
},
|
|
38504
|
+
ctx.clientSettings
|
|
38505
|
+
);
|
|
38506
|
+
return {
|
|
38507
|
+
data: {
|
|
38508
|
+
content: result.content,
|
|
38509
|
+
rawText: result.content
|
|
38510
|
+
},
|
|
38511
|
+
meta: {
|
|
38512
|
+
model: result.model,
|
|
38513
|
+
provider: "openai-compatible"
|
|
38514
|
+
}
|
|
38515
|
+
};
|
|
37977
38516
|
}
|
|
37978
|
-
|
|
37979
|
-
|
|
38517
|
+
};
|
|
38518
|
+
|
|
38519
|
+
// src/common/aiApi/tasks/coreStructuredMultimodal.ts
|
|
38520
|
+
function isStructuredMultimodalInput(input) {
|
|
38521
|
+
if (!input || typeof input !== "object") return false;
|
|
38522
|
+
const value = input;
|
|
38523
|
+
return typeof value.systemPrompt === "string" && typeof value.userPrompt === "string";
|
|
38524
|
+
}
|
|
38525
|
+
var coreStructuredMultimodalTask = {
|
|
38526
|
+
id: CORE_STRUCTURED_MULTIMODAL_TASK_ID,
|
|
38527
|
+
description: "\u901A\u7528\u7ED3\u6784\u5316\u591A\u6A21\u6001\u4EFB\u52A1\uFF1A\u6587\u672C + \u53EF\u9009\u56FE\u7247/\u8BED\u97F3 \u2192 JSON",
|
|
38528
|
+
validateInput(input) {
|
|
38529
|
+
if (!isStructuredMultimodalInput(input)) {
|
|
38530
|
+
throw new Error("systemPrompt \u4E0E userPrompt \u4E3A\u5FC5\u586B");
|
|
38531
|
+
}
|
|
38532
|
+
const config = resolveAiConnectionConfig(input.connection);
|
|
38533
|
+
assertValidMultimodalMedia(input.media, {
|
|
38534
|
+
maxImageBytes: config?.maxImageBytes ?? 5 * 1024 * 1024,
|
|
38535
|
+
maxAudioBytes: config?.maxAudioBytes ?? 25 * 1024 * 1024
|
|
38536
|
+
});
|
|
38537
|
+
return input;
|
|
38538
|
+
},
|
|
38539
|
+
async execute(input, ctx) {
|
|
38540
|
+
const schemaHint = input.jsonSchemaHint ? `
|
|
38541
|
+
|
|
38542
|
+
\u8BF7\u4E25\u683C\u8F93\u51FA JSON \u5BF9\u8C61\uFF0C\u7ED3\u6784\u53C2\u8003\uFF1A
|
|
38543
|
+
${input.jsonSchemaHint}` : "\n\n\u8BF7\u4E25\u683C\u8F93\u51FA JSON \u5BF9\u8C61\uFF0C\u4E0D\u8981\u5305\u542B Markdown \u4EE3\u7801\u5757\u3002";
|
|
38544
|
+
const result = await callMultimodalChat(
|
|
38545
|
+
{
|
|
38546
|
+
systemPrompt: input.systemPrompt,
|
|
38547
|
+
userPrompt: `${input.userPrompt}${schemaHint}`,
|
|
38548
|
+
media: input.media,
|
|
38549
|
+
model: input.model,
|
|
38550
|
+
temperature: input.temperature ?? 0.2,
|
|
38551
|
+
maxTokens: input.maxTokens,
|
|
38552
|
+
jsonMode: true,
|
|
38553
|
+
audioStrategy: input.audioStrategy,
|
|
38554
|
+
connection: input.connection
|
|
38555
|
+
},
|
|
38556
|
+
ctx.clientSettings
|
|
38557
|
+
);
|
|
38558
|
+
const json2 = extractJsonObject(result.content);
|
|
38559
|
+
return {
|
|
38560
|
+
data: {
|
|
38561
|
+
json: json2,
|
|
38562
|
+
rawText: result.content
|
|
38563
|
+
},
|
|
38564
|
+
meta: {
|
|
38565
|
+
model: result.model,
|
|
38566
|
+
provider: "openai-compatible",
|
|
38567
|
+
rawSummary: result.audioHandling ? `audio=${result.audioHandling}` : void 0
|
|
38568
|
+
}
|
|
38569
|
+
};
|
|
37980
38570
|
}
|
|
37981
38571
|
};
|
|
37982
|
-
|
|
37983
|
-
|
|
38572
|
+
|
|
38573
|
+
// src/common/aiApi/tasks/coreConnectivityTest.ts
|
|
38574
|
+
var coreConnectivityTestTask = {
|
|
38575
|
+
id: CORE_CONNECTIVITY_TEST_TASK_ID,
|
|
38576
|
+
description: "\u6D4B\u8BD5 AI API \u8FDE\u901A\u6027\uFF08\u8F7B\u91CF\u6587\u672C\u8BF7\u6C42\uFF09",
|
|
38577
|
+
validateInput() {
|
|
38578
|
+
return {};
|
|
38579
|
+
},
|
|
38580
|
+
async execute(_input, ctx) {
|
|
38581
|
+
const config = resolveAiConnectionConfig(ctx.clientSettings);
|
|
38582
|
+
if (!config) {
|
|
38583
|
+
throw new Error("\u672A\u914D\u7F6E AI API Key");
|
|
38584
|
+
}
|
|
38585
|
+
const result = await callChat({
|
|
38586
|
+
baseUrl: config.baseUrl,
|
|
38587
|
+
apiKey: config.apiKey,
|
|
38588
|
+
model: config.textModel,
|
|
38589
|
+
systemPrompt: "You are a connectivity probe. Reply with JSON only.",
|
|
38590
|
+
userPrompt: 'Return JSON: {"ok":true,"reply":"OK"}',
|
|
38591
|
+
temperature: 0,
|
|
38592
|
+
maxTokens: 32,
|
|
38593
|
+
timeoutMs: config.timeoutMs
|
|
38594
|
+
});
|
|
38595
|
+
let ok = false;
|
|
38596
|
+
let reply = result.content.trim();
|
|
38597
|
+
try {
|
|
38598
|
+
const json2 = extractJsonObject(result.content);
|
|
38599
|
+
ok = json2.ok === true || json2.ok === "true";
|
|
38600
|
+
reply = String(json2.reply ?? result.content).trim();
|
|
38601
|
+
} catch {
|
|
38602
|
+
ok = /ok/i.test(result.content);
|
|
38603
|
+
}
|
|
38604
|
+
if (!ok && !reply) {
|
|
38605
|
+
throw new Error("\u6A21\u578B\u672A\u8FD4\u56DE\u6709\u6548\u54CD\u5E94");
|
|
38606
|
+
}
|
|
38607
|
+
return {
|
|
38608
|
+
data: { ok: true, reply: reply || "OK" },
|
|
38609
|
+
meta: {
|
|
38610
|
+
model: result.model,
|
|
38611
|
+
provider: "openai-compatible"
|
|
38612
|
+
}
|
|
38613
|
+
};
|
|
38614
|
+
}
|
|
37984
38615
|
};
|
|
37985
38616
|
|
|
38617
|
+
// src/common/aiApi/registerCoreTasks.ts
|
|
38618
|
+
var registered = false;
|
|
38619
|
+
function registerCoreAiTasks() {
|
|
38620
|
+
if (registered) return;
|
|
38621
|
+
registerAiTask(coreLlmCompletionTask);
|
|
38622
|
+
registerAiTask(coreStructuredMultimodalTask);
|
|
38623
|
+
registerAiTask(coreConnectivityTestTask);
|
|
38624
|
+
registered = true;
|
|
38625
|
+
}
|
|
38626
|
+
var ensureCoreAiTasksRegistered = registerCoreAiTasks;
|
|
38627
|
+
function resetCoreAiTasksForTest() {
|
|
38628
|
+
registered = false;
|
|
38629
|
+
}
|
|
38630
|
+
|
|
37986
38631
|
exports.About = AboutWithDefaults_default;
|
|
37987
38632
|
exports.AboutBase = About_default;
|
|
37988
38633
|
exports.AlertDialog = Dialog;
|
|
@@ -38005,6 +38650,9 @@ exports.BackgroundRemover = BackgroundRemover;
|
|
|
38005
38650
|
exports.Badge = Badge;
|
|
38006
38651
|
exports.BoothVaultService = BoothVaultService;
|
|
38007
38652
|
exports.Button = Button;
|
|
38653
|
+
exports.CORE_CONNECTIVITY_TEST_TASK_ID = CORE_CONNECTIVITY_TEST_TASK_ID;
|
|
38654
|
+
exports.CORE_LLM_COMPLETION_TASK_ID = CORE_LLM_COMPLETION_TASK_ID;
|
|
38655
|
+
exports.CORE_STRUCTURED_MULTIMODAL_TASK_ID = CORE_STRUCTURED_MULTIMODAL_TASK_ID;
|
|
38008
38656
|
exports.Card = Card;
|
|
38009
38657
|
exports.CardContent = CardContent;
|
|
38010
38658
|
exports.CardDescription = CardDescription;
|
|
@@ -38023,7 +38671,7 @@ exports.DEFAULT_FESTIVAL_CARD_CONFIG = DEFAULT_FESTIVAL_CARD_CONFIG;
|
|
|
38023
38671
|
exports.DEFAULT_MAX_ACTIVE_FIREWORKS = DEFAULT_MAX_ACTIVE_FIREWORKS;
|
|
38024
38672
|
exports.DEFAULT_MAX_PARTICLES = DEFAULT_MAX_PARTICLES;
|
|
38025
38673
|
exports.DEFAULT_OPENAI_BASE_URL = DEFAULT_OPENAI_BASE_URL;
|
|
38026
|
-
exports.
|
|
38674
|
+
exports.DEFAULT_TEXT_MODEL = DEFAULT_TEXT_MODEL2;
|
|
38027
38675
|
exports.DanmakuPanel = DanmakuPanel;
|
|
38028
38676
|
exports.Dialog = Dialog;
|
|
38029
38677
|
exports.DialogClose = DialogClose;
|
|
@@ -38073,7 +38721,6 @@ exports.GenericOrderManager = GenericOrderManager;
|
|
|
38073
38721
|
exports.Grid = Grid;
|
|
38074
38722
|
exports.Home = Home_default;
|
|
38075
38723
|
exports.ImageMappingPanel = ImageMappingPanel;
|
|
38076
|
-
exports.InMemorySkillRegistry = InMemorySkillRegistry;
|
|
38077
38724
|
exports.Input = Input;
|
|
38078
38725
|
exports.Label = Label;
|
|
38079
38726
|
exports.LocalImageMappingPanel = LocalImageMappingPanel;
|
|
@@ -38143,17 +38790,29 @@ exports.TooltipProvider = TooltipProvider;
|
|
|
38143
38790
|
exports.TooltipTrigger = TooltipTrigger;
|
|
38144
38791
|
exports.UserInfoBar = UserInfoBar;
|
|
38145
38792
|
exports.WebSocketTransport = WebSocketTransport;
|
|
38146
|
-
exports.
|
|
38793
|
+
exports.appendTranscriptionsToPrompt = appendTranscriptionsToPrompt;
|
|
38147
38794
|
exports.arrayUtils = arrayUtils;
|
|
38795
|
+
exports.assertMultimodalCapableModel = assertMultimodalCapableModel;
|
|
38796
|
+
exports.assertValidAudioInput = assertValidAudioInput;
|
|
38797
|
+
exports.assertValidImageInput = assertValidImageInput;
|
|
38798
|
+
exports.assertValidMultimodalMedia = assertValidMultimodalMedia;
|
|
38799
|
+
exports.assertVisionCapableModel = assertVisionCapableModel;
|
|
38148
38800
|
exports.badgeVariants = badgeVariants;
|
|
38801
|
+
exports.base64ToBlob = base64ToBlob;
|
|
38149
38802
|
exports.bubbleShooter = bubbleShooter_exports;
|
|
38803
|
+
exports.buildMultimodalMessages = buildMultimodalMessages;
|
|
38150
38804
|
exports.business = business_exports;
|
|
38151
38805
|
exports.buttonVariants = buttonVariants;
|
|
38806
|
+
exports.callChat = callChat;
|
|
38807
|
+
exports.callCompletion = callCompletion;
|
|
38808
|
+
exports.callMultimodalChat = callMultimodalChat;
|
|
38152
38809
|
exports.checkVoteEligibility = checkVoteEligibility;
|
|
38810
|
+
exports.clearAiTasksForTest = clearAiTasksForTest;
|
|
38153
38811
|
exports.cn = cn;
|
|
38154
38812
|
exports.common = common_exports;
|
|
38155
|
-
exports.
|
|
38156
|
-
exports.
|
|
38813
|
+
exports.coreConnectivityTestTask = coreConnectivityTestTask;
|
|
38814
|
+
exports.coreLlmCompletionTask = coreLlmCompletionTask;
|
|
38815
|
+
exports.coreStructuredMultimodalTask = coreStructuredMultimodalTask;
|
|
38157
38816
|
exports.createCreateSubmissionHandler = createCreateSubmissionHandler;
|
|
38158
38817
|
exports.createDefaultMikuContestConfig = createDefaultMikuContestConfig;
|
|
38159
38818
|
exports.createExportSubmissionsHandler = createExportSubmissionsHandler;
|
|
@@ -38165,21 +38824,28 @@ exports.createMikuContestApiClient = createMikuContestApiClient;
|
|
|
38165
38824
|
exports.createMikuContestDrizzlePersistenceAdapter = createMikuContestDrizzlePersistenceAdapter;
|
|
38166
38825
|
exports.createMikuContestPersistentService = createMikuContestPersistentService;
|
|
38167
38826
|
exports.createMikuContestService = createMikuContestService;
|
|
38168
|
-
exports.createOpenAICompatibleProvider = createOpenAICompatibleProvider;
|
|
38169
38827
|
exports.createResetVotesHandler = createResetVotesHandler;
|
|
38170
38828
|
exports.createReviewSubmissionHandler = createReviewSubmissionHandler;
|
|
38171
38829
|
exports.createSetVoterRestrictionHandler = createSetVoterRestrictionHandler;
|
|
38172
|
-
exports.createSkillRegistry = createSkillRegistry;
|
|
38173
38830
|
exports.createUpdateContestConfigHandler = createUpdateContestConfigHandler;
|
|
38174
38831
|
exports.createVoteHandler = createVoteHandler;
|
|
38175
38832
|
exports.debugUtils = debugUtils;
|
|
38176
38833
|
exports.defaultMikuVotingRules = defaultMikuVotingRules;
|
|
38177
38834
|
exports.defaultVocaloidBoothConfig = defaultVocaloidBoothConfig;
|
|
38835
|
+
exports.detectVisionMessageFormat = detectVisionMessageFormat;
|
|
38836
|
+
exports.ensureCoreAiTasksRegistered = ensureCoreAiTasksRegistered;
|
|
38178
38837
|
exports.errorUtils = errorUtils;
|
|
38838
|
+
exports.extractJsonObject = extractJsonObject;
|
|
38839
|
+
exports.fileToAiAudioInput = fileToAiAudioInput;
|
|
38840
|
+
exports.fileToAiImageInput = fileToAiImageInput;
|
|
38179
38841
|
exports.fileUtils = fileUtils;
|
|
38842
|
+
exports.filterChatModels = filterChatModels;
|
|
38180
38843
|
exports.filterExperiments = filterExperiments;
|
|
38844
|
+
exports.filterSttModels = filterSttModels;
|
|
38845
|
+
exports.filterVisionModels = filterVisionModels;
|
|
38181
38846
|
exports.formatTime = formatTime;
|
|
38182
38847
|
exports.generateMatchCode = generateMatchCode;
|
|
38848
|
+
exports.getAiTask = getAiTask;
|
|
38183
38849
|
exports.getAllTags = getAllTags;
|
|
38184
38850
|
exports.getCategoryColor = getCategoryColor;
|
|
38185
38851
|
exports.getCategoryDisplayName = getCategoryDisplayName;
|
|
@@ -38187,7 +38853,15 @@ exports.getCompletionFilterDisplayName = getCompletionFilterDisplayName;
|
|
|
38187
38853
|
exports.getCompletionStatusColor = getCompletionStatusColor;
|
|
38188
38854
|
exports.getCompletionStatusText = getCompletionStatusText;
|
|
38189
38855
|
exports.getExperimentCounts = getExperimentCounts;
|
|
38856
|
+
exports.isAudioInputError = isAudioInputError;
|
|
38857
|
+
exports.isImageUrlVariantError = isImageUrlVariantError;
|
|
38858
|
+
exports.isKnownTextOnlyModel = isKnownTextOnlyModel;
|
|
38859
|
+
exports.isLikelyNativeAudioChatModel = isLikelyNativeAudioChatModel;
|
|
38860
|
+
exports.isLikelySttModel = isLikelySttModel;
|
|
38861
|
+
exports.isLikelyVisionModel = isLikelyVisionModel;
|
|
38190
38862
|
exports.japaneseUtils = japaneseUtils;
|
|
38863
|
+
exports.listAiTasks = listAiTasks;
|
|
38864
|
+
exports.listOpenAiCompatibleModels = listOpenAiCompatibleModels;
|
|
38191
38865
|
exports.logger = logger;
|
|
38192
38866
|
exports.mikuContestConfigs = mikuContestConfigs;
|
|
38193
38867
|
exports.mikuContestDbService = mikuContestDbService;
|
|
@@ -38195,20 +38869,32 @@ exports.mikuContestNotices = mikuContestNotices;
|
|
|
38195
38869
|
exports.mikuContestSubmissions = mikuContestSubmissions;
|
|
38196
38870
|
exports.mikuContestVoterRestrictions = mikuContestVoterRestrictions;
|
|
38197
38871
|
exports.mikuContestVotes = mikuContestVotes;
|
|
38872
|
+
exports.mimeToAudioFormat = mimeToAudioFormat;
|
|
38198
38873
|
exports.miniappService = miniapp_exports;
|
|
38199
38874
|
exports.miniappUI = miniapp_exports2;
|
|
38200
38875
|
exports.normalizeFestivalCardConfig = normalizeFestivalCardConfig;
|
|
38201
38876
|
exports.normalizeMatchCode = normalizeMatchCode;
|
|
38202
|
-
exports.normalizePromptVariables = normalizePromptVariables;
|
|
38203
38877
|
exports.normalizeVocaloidBoothConfig = normalizeVocaloidBoothConfig;
|
|
38878
|
+
exports.pickDefaultSttModel = pickDefaultSttModel;
|
|
38879
|
+
exports.pickDefaultVisionModel = pickDefaultVisionModel;
|
|
38880
|
+
exports.registerAiTask = registerAiTask;
|
|
38881
|
+
exports.registerCoreAiTasks = registerCoreAiTasks;
|
|
38882
|
+
exports.requestJson = requestJson;
|
|
38883
|
+
exports.requireAiConnectionConfig = requireAiConnectionConfig;
|
|
38884
|
+
exports.resetCoreAiTasksForTest = resetCoreAiTasksForTest;
|
|
38204
38885
|
exports.resizeFestivalCardPages = resizeFestivalCardPages;
|
|
38886
|
+
exports.resolveAiConnectionConfig = resolveAiConnectionConfig;
|
|
38887
|
+
exports.resolveAudioHandling = resolveAudioHandling;
|
|
38205
38888
|
exports.resolveScreenReceiverSignalUrl = resolveScreenReceiverSignalUrl;
|
|
38206
|
-
exports.
|
|
38889
|
+
exports.runAiTask = runAiTask;
|
|
38207
38890
|
exports.sortByVotesDesc = sortByVotesDesc;
|
|
38208
38891
|
exports.sortExperiments = sortExperiments;
|
|
38892
|
+
exports.splitMediaByKind = splitMediaByKind;
|
|
38209
38893
|
exports.stringUtils = stringUtils;
|
|
38894
|
+
exports.toVisionApiErrorMessage = toVisionApiErrorMessage;
|
|
38210
38895
|
exports.toVoteDayKey = toVoteDayKey;
|
|
38211
|
-
exports.
|
|
38896
|
+
exports.transcribeAudio = transcribeAudio;
|
|
38897
|
+
exports.transcribeAudios = transcribeAudios;
|
|
38212
38898
|
exports.useAsyncStorage = useAsyncStorage;
|
|
38213
38899
|
exports.useBackgroundRemoval = useBackgroundRemoval;
|
|
38214
38900
|
exports.useDanmakuController = useDanmakuController;
|