@chatluna/v1-shared-adapter 1.0.20 → 1.0.22
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/lib/client.d.ts +6 -0
- package/lib/index.cjs +110 -22
- package/lib/index.mjs +108 -22
- package/lib/requester.d.ts +6 -0
- package/package.json +6 -6
package/lib/client.d.ts
CHANGED
|
@@ -1,4 +1,10 @@
|
|
|
1
1
|
import { ModelInfo } from 'koishi-plugin-chatluna/llm-core/platform/types';
|
|
2
|
+
export type OpenAIReasoningEffort = 'none' | 'minimal' | 'low' | 'medium' | 'high' | 'xhigh';
|
|
3
|
+
export declare function parseOpenAIModelNameWithReasoningEffort(modelName: string): {
|
|
4
|
+
model: string;
|
|
5
|
+
reasoningEffort?: OpenAIReasoningEffort;
|
|
6
|
+
};
|
|
7
|
+
export declare function normalizeOpenAIModelName(modelName: string): string;
|
|
2
8
|
export declare function isEmbeddingModel(modelName: string): boolean;
|
|
3
9
|
export declare function isNonLLMModel(modelName: string): boolean;
|
|
4
10
|
export declare function getModelMaxContextSize(info: ModelInfo): number;
|
package/lib/index.cjs
CHANGED
|
@@ -36,6 +36,8 @@ __export(index_exports, {
|
|
|
36
36
|
isNonLLMModel: () => isNonLLMModel,
|
|
37
37
|
langchainMessageToOpenAIMessage: () => langchainMessageToOpenAIMessage,
|
|
38
38
|
messageTypeToOpenAIRole: () => messageTypeToOpenAIRole,
|
|
39
|
+
normalizeOpenAIModelName: () => normalizeOpenAIModelName,
|
|
40
|
+
parseOpenAIModelNameWithReasoningEffort: () => parseOpenAIModelNameWithReasoningEffort,
|
|
39
41
|
processDeepSeekThinkMessages: () => processDeepSeekThinkMessages,
|
|
40
42
|
processReasoningContent: () => processReasoningContent,
|
|
41
43
|
processResponse: () => processResponse,
|
|
@@ -48,6 +50,35 @@ module.exports = __toCommonJS(index_exports);
|
|
|
48
50
|
|
|
49
51
|
// src/client.ts
|
|
50
52
|
var import_count_tokens = require("koishi-plugin-chatluna/llm-core/utils/count_tokens");
|
|
53
|
+
function parseOpenAIModelNameWithReasoningEffort(modelName) {
|
|
54
|
+
let model = modelName;
|
|
55
|
+
let reasoningEffort;
|
|
56
|
+
const explicitMatch = model.match(
|
|
57
|
+
/-(none|minimal|low|medium|high|xhigh|tiny)-thinking$/
|
|
58
|
+
);
|
|
59
|
+
if (explicitMatch?.[1]) {
|
|
60
|
+
const level = explicitMatch[1];
|
|
61
|
+
model = model.replace(`-${level}-thinking`, "");
|
|
62
|
+
reasoningEffort = level === "tiny" ? "minimal" : level;
|
|
63
|
+
return { model, reasoningEffort };
|
|
64
|
+
}
|
|
65
|
+
if (model.endsWith("-non-thinking")) {
|
|
66
|
+
model = model.slice(0, -"-non-thinking".length);
|
|
67
|
+
reasoningEffort = "none";
|
|
68
|
+
return { model, reasoningEffort };
|
|
69
|
+
}
|
|
70
|
+
if (model.endsWith("-thinking")) {
|
|
71
|
+
model = model.slice(0, -"-thinking".length);
|
|
72
|
+
reasoningEffort = "medium";
|
|
73
|
+
return { model, reasoningEffort };
|
|
74
|
+
}
|
|
75
|
+
return { model };
|
|
76
|
+
}
|
|
77
|
+
__name(parseOpenAIModelNameWithReasoningEffort, "parseOpenAIModelNameWithReasoningEffort");
|
|
78
|
+
function normalizeOpenAIModelName(modelName) {
|
|
79
|
+
return parseOpenAIModelNameWithReasoningEffort(modelName).model;
|
|
80
|
+
}
|
|
81
|
+
__name(normalizeOpenAIModelName, "normalizeOpenAIModelName");
|
|
51
82
|
function isEmbeddingModel(modelName) {
|
|
52
83
|
return modelName.includes("embed") || modelName.includes("bge") || modelName.includes("instructor-large") || modelName.includes("m3e");
|
|
53
84
|
}
|
|
@@ -66,7 +97,7 @@ function getModelMaxContextSize(info) {
|
|
|
66
97
|
if (maxTokens != null) {
|
|
67
98
|
return maxTokens;
|
|
68
99
|
}
|
|
69
|
-
const modelName = info.name;
|
|
100
|
+
const modelName = normalizeOpenAIModelName(info.name);
|
|
70
101
|
if (modelName.startsWith("gpt") || modelName.startsWith("o1") || modelName.startsWith("o3") || modelName.startsWith("o4")) {
|
|
71
102
|
return (0, import_count_tokens.getModelContextSize)(modelName);
|
|
72
103
|
}
|
|
@@ -128,7 +159,7 @@ var imageModelMatchers = [
|
|
|
128
159
|
"grok-4"
|
|
129
160
|
].map((pattern) => createGlobMatcher(pattern));
|
|
130
161
|
function supportImageInput(modelName) {
|
|
131
|
-
const lowerModel = modelName.toLowerCase();
|
|
162
|
+
const lowerModel = normalizeOpenAIModelName(modelName).toLowerCase();
|
|
132
163
|
return imageModelMatchers.some((matcher) => matcher(lowerModel));
|
|
133
164
|
}
|
|
134
165
|
__name(supportImageInput, "supportImageInput");
|
|
@@ -145,7 +176,8 @@ var import_string = require("koishi-plugin-chatluna/utils/string");
|
|
|
145
176
|
var import_types = require("@langchain/core/utils/types");
|
|
146
177
|
async function langchainMessageToOpenAIMessage(messages, plugin, model, supportImageInput2, removeSystemMessage) {
|
|
147
178
|
const result = [];
|
|
148
|
-
const
|
|
179
|
+
const normalizedModel = model ? normalizeOpenAIModelName(model) : model;
|
|
180
|
+
const isDeepseekThinkModel = normalizedModel?.includes("deepseek-reasoner");
|
|
149
181
|
for (const rawMessage of messages) {
|
|
150
182
|
const role = messageTypeToOpenAIRole(rawMessage.getType());
|
|
151
183
|
const msg = {
|
|
@@ -175,25 +207,38 @@ async function langchainMessageToOpenAIMessage(messages, plugin, model, supportI
|
|
|
175
207
|
}
|
|
176
208
|
}
|
|
177
209
|
const images = rawMessage.additional_kwargs.images;
|
|
178
|
-
const lowerModel =
|
|
179
|
-
if ((lowerModel?.includes("vision") || lowerModel?.includes("gpt-4o") || lowerModel?.includes("claude") || lowerModel?.includes("gemini") || lowerModel?.includes("qwen-vl") || lowerModel?.includes("omni") || lowerModel?.includes("qwen2.5-vl") || lowerModel?.includes("qwen2.5-omni") || lowerModel?.includes("qwen-omni") || lowerModel?.includes("qwen2-vl") || lowerModel?.includes("qvq") ||
|
|
210
|
+
const lowerModel = normalizedModel?.toLowerCase() ?? "";
|
|
211
|
+
if ((lowerModel?.includes("vision") || lowerModel?.includes("gpt-4o") || lowerModel?.includes("claude") || lowerModel?.includes("gemini") || lowerModel?.includes("qwen-vl") || lowerModel?.includes("omni") || lowerModel?.includes("qwen2.5-vl") || lowerModel?.includes("qwen2.5-omni") || lowerModel?.includes("qwen-omni") || lowerModel?.includes("qwen2-vl") || lowerModel?.includes("qvq") || normalizedModel?.includes("o1") || normalizedModel?.includes("o4") || normalizedModel?.includes("o3") || normalizedModel?.includes("gpt-4.1") || normalizedModel?.includes("gpt-5") || supportImageInput2) && images != null) {
|
|
180
212
|
msg.content = [
|
|
181
213
|
{
|
|
182
214
|
type: "text",
|
|
183
215
|
text: rawMessage.content
|
|
184
216
|
}
|
|
185
217
|
];
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
218
|
+
const imageContents = await Promise.all(
|
|
219
|
+
images.map(async (image) => {
|
|
220
|
+
try {
|
|
221
|
+
const url = await fetchImageUrl(plugin, {
|
|
222
|
+
type: "image_url",
|
|
223
|
+
image_url: { url: image }
|
|
224
|
+
});
|
|
225
|
+
return {
|
|
226
|
+
type: "image_url",
|
|
227
|
+
image_url: {
|
|
228
|
+
url,
|
|
229
|
+
detail: "low"
|
|
230
|
+
}
|
|
231
|
+
};
|
|
232
|
+
} catch {
|
|
233
|
+
return null;
|
|
192
234
|
}
|
|
193
|
-
})
|
|
194
|
-
|
|
235
|
+
})
|
|
236
|
+
);
|
|
237
|
+
msg.content.push(
|
|
238
|
+
...imageContents.filter((content) => content != null)
|
|
239
|
+
);
|
|
195
240
|
} else if (Array.isArray(msg.content) && msg.content.length > 0) {
|
|
196
|
-
|
|
241
|
+
const mappedContent = await Promise.all(
|
|
197
242
|
msg.content.map(async (content) => {
|
|
198
243
|
if (!(0, import_string.isMessageContentImageUrl)(content)) return content;
|
|
199
244
|
try {
|
|
@@ -206,10 +251,11 @@ async function langchainMessageToOpenAIMessage(messages, plugin, model, supportI
|
|
|
206
251
|
}
|
|
207
252
|
};
|
|
208
253
|
} catch {
|
|
209
|
-
return
|
|
254
|
+
return null;
|
|
210
255
|
}
|
|
211
256
|
})
|
|
212
257
|
);
|
|
258
|
+
msg.content = mappedContent.filter((content) => content != null);
|
|
213
259
|
}
|
|
214
260
|
result.push(msg);
|
|
215
261
|
}
|
|
@@ -470,12 +516,14 @@ var import_string2 = require("koishi-plugin-chatluna/utils/string");
|
|
|
470
516
|
var import_logger = require("koishi-plugin-chatluna/utils/logger");
|
|
471
517
|
var import_object = require("koishi-plugin-chatluna/utils/object");
|
|
472
518
|
async function buildChatCompletionParams(params, plugin, enableGoogleSearch, supportImageInput2) {
|
|
519
|
+
const parsedModel = parseOpenAIModelNameWithReasoningEffort(params.model);
|
|
520
|
+
const normalizedModel = parsedModel.model;
|
|
473
521
|
const base = {
|
|
474
|
-
model:
|
|
522
|
+
model: normalizedModel,
|
|
475
523
|
messages: await langchainMessageToOpenAIMessage(
|
|
476
524
|
params.input,
|
|
477
525
|
plugin,
|
|
478
|
-
|
|
526
|
+
normalizedModel,
|
|
479
527
|
supportImageInput2
|
|
480
528
|
),
|
|
481
529
|
tools: enableGoogleSearch || params.tools != null ? formatToolsToOpenAITools(
|
|
@@ -483,20 +531,28 @@ async function buildChatCompletionParams(params, plugin, enableGoogleSearch, sup
|
|
|
483
531
|
enableGoogleSearch
|
|
484
532
|
) : void 0,
|
|
485
533
|
stop: params.stop || void 0,
|
|
486
|
-
max_tokens:
|
|
534
|
+
max_tokens: normalizedModel.includes("vision") ? void 0 : params.maxTokens,
|
|
487
535
|
temperature: params.temperature === 0 ? void 0 : params.temperature,
|
|
488
536
|
presence_penalty: params.presencePenalty === 0 ? void 0 : params.presencePenalty,
|
|
489
537
|
frequency_penalty: params.frequencyPenalty === 0 ? void 0 : params.frequencyPenalty,
|
|
490
538
|
n: params.n,
|
|
491
539
|
top_p: params.topP,
|
|
492
540
|
prompt_cache_key: params.id,
|
|
541
|
+
prompt_cache_retention: void 0,
|
|
542
|
+
prediction: void 0,
|
|
543
|
+
reasoning_effort: parsedModel.reasoningEffort,
|
|
544
|
+
response_format: void 0,
|
|
545
|
+
safety_identifier: void 0,
|
|
546
|
+
service_tier: void 0,
|
|
493
547
|
stream: true,
|
|
494
548
|
logit_bias: params.logitBias,
|
|
495
549
|
stream_options: {
|
|
496
550
|
include_usage: true
|
|
497
551
|
}
|
|
498
552
|
};
|
|
499
|
-
|
|
553
|
+
const lowerModel = normalizedModel.toLowerCase();
|
|
554
|
+
const isOpenAIReasoningModel = lowerModel.startsWith("o1") || lowerModel.startsWith("o3") || lowerModel.startsWith("o4") || lowerModel.startsWith("gpt-5");
|
|
555
|
+
if (isOpenAIReasoningModel) {
|
|
500
556
|
delete base.temperature;
|
|
501
557
|
delete base.presence_penalty;
|
|
502
558
|
delete base.frequency_penalty;
|
|
@@ -653,7 +709,7 @@ async function* completionStream(requestContext, params, completionUrl = "chat/c
|
|
|
653
709
|
const iterator = (0, import_sse.sseIterable)(response);
|
|
654
710
|
yield* processStreamResponse(requestContext, iterator);
|
|
655
711
|
} catch (e) {
|
|
656
|
-
if (requestContext.ctx.chatluna.
|
|
712
|
+
if (requestContext.ctx.chatluna.currentConfig.isLog) {
|
|
657
713
|
await (0, import_logger.trackLogToLocal)(
|
|
658
714
|
"Request",
|
|
659
715
|
JSON.stringify(chatCompletionParams),
|
|
@@ -687,7 +743,7 @@ async function completion(requestContext, params, completionUrl = "chat/completi
|
|
|
687
743
|
);
|
|
688
744
|
return await processResponse(requestContext, response);
|
|
689
745
|
} catch (e) {
|
|
690
|
-
if (requestContext.ctx.chatluna.
|
|
746
|
+
if (requestContext.ctx.chatluna.currentConfig.isLog) {
|
|
691
747
|
await (0, import_logger.trackLogToLocal)(
|
|
692
748
|
"Request",
|
|
693
749
|
JSON.stringify(chatCompletionParams),
|
|
@@ -735,7 +791,37 @@ async function getModels(requestContext, config) {
|
|
|
735
791
|
);
|
|
736
792
|
data = await response.text();
|
|
737
793
|
data = JSON.parse(data);
|
|
738
|
-
|
|
794
|
+
const rawModels = data.data.map((model) => model.id);
|
|
795
|
+
const expanded = [];
|
|
796
|
+
const seen = /* @__PURE__ */ new Set();
|
|
797
|
+
const isOpenAIReasoningModel = /* @__PURE__ */ __name((model) => {
|
|
798
|
+
const lower = model.toLowerCase();
|
|
799
|
+
return lower.startsWith("gpt-5") || lower.startsWith("o1") || lower.startsWith("o3") || lower.startsWith("o4");
|
|
800
|
+
}, "isOpenAIReasoningModel");
|
|
801
|
+
const hasThinkingTag = /* @__PURE__ */ __name((model) => {
|
|
802
|
+
const lower = model.toLowerCase();
|
|
803
|
+
return lower.includes("thinking") || ["minimal", "low", "medium", "high", "xhigh"].some(
|
|
804
|
+
(level) => lower.includes(level)
|
|
805
|
+
);
|
|
806
|
+
}, "hasThinkingTag");
|
|
807
|
+
const push = /* @__PURE__ */ __name((model) => {
|
|
808
|
+
if (seen.has(model)) return;
|
|
809
|
+
seen.add(model);
|
|
810
|
+
expanded.push(model);
|
|
811
|
+
}, "push");
|
|
812
|
+
for (const model of rawModels) {
|
|
813
|
+
push(model);
|
|
814
|
+
if (!isOpenAIReasoningModel(model)) continue;
|
|
815
|
+
if (hasThinkingTag(model)) continue;
|
|
816
|
+
push(`${model}-non-thinking`);
|
|
817
|
+
push(`${model}`);
|
|
818
|
+
push(`${model}-minimal-thinking`);
|
|
819
|
+
push(`${model}-low-thinking`);
|
|
820
|
+
push(`${model}-medium-thinking`);
|
|
821
|
+
push(`${model}-high-thinking`);
|
|
822
|
+
push(`${model}-xhigh-thinking`);
|
|
823
|
+
}
|
|
824
|
+
return expanded;
|
|
739
825
|
} catch (e) {
|
|
740
826
|
if (e instanceof import_error.ChatLunaError) {
|
|
741
827
|
throw e;
|
|
@@ -768,6 +854,8 @@ __name(createRequestContext, "createRequestContext");
|
|
|
768
854
|
isNonLLMModel,
|
|
769
855
|
langchainMessageToOpenAIMessage,
|
|
770
856
|
messageTypeToOpenAIRole,
|
|
857
|
+
normalizeOpenAIModelName,
|
|
858
|
+
parseOpenAIModelNameWithReasoningEffort,
|
|
771
859
|
processDeepSeekThinkMessages,
|
|
772
860
|
processReasoningContent,
|
|
773
861
|
processResponse,
|
package/lib/index.mjs
CHANGED
|
@@ -3,6 +3,35 @@ var __name = (target, value) => __defProp(target, "name", { value, configurable:
|
|
|
3
3
|
|
|
4
4
|
// src/client.ts
|
|
5
5
|
import { getModelContextSize } from "koishi-plugin-chatluna/llm-core/utils/count_tokens";
|
|
6
|
+
function parseOpenAIModelNameWithReasoningEffort(modelName) {
|
|
7
|
+
let model = modelName;
|
|
8
|
+
let reasoningEffort;
|
|
9
|
+
const explicitMatch = model.match(
|
|
10
|
+
/-(none|minimal|low|medium|high|xhigh|tiny)-thinking$/
|
|
11
|
+
);
|
|
12
|
+
if (explicitMatch?.[1]) {
|
|
13
|
+
const level = explicitMatch[1];
|
|
14
|
+
model = model.replace(`-${level}-thinking`, "");
|
|
15
|
+
reasoningEffort = level === "tiny" ? "minimal" : level;
|
|
16
|
+
return { model, reasoningEffort };
|
|
17
|
+
}
|
|
18
|
+
if (model.endsWith("-non-thinking")) {
|
|
19
|
+
model = model.slice(0, -"-non-thinking".length);
|
|
20
|
+
reasoningEffort = "none";
|
|
21
|
+
return { model, reasoningEffort };
|
|
22
|
+
}
|
|
23
|
+
if (model.endsWith("-thinking")) {
|
|
24
|
+
model = model.slice(0, -"-thinking".length);
|
|
25
|
+
reasoningEffort = "medium";
|
|
26
|
+
return { model, reasoningEffort };
|
|
27
|
+
}
|
|
28
|
+
return { model };
|
|
29
|
+
}
|
|
30
|
+
__name(parseOpenAIModelNameWithReasoningEffort, "parseOpenAIModelNameWithReasoningEffort");
|
|
31
|
+
function normalizeOpenAIModelName(modelName) {
|
|
32
|
+
return parseOpenAIModelNameWithReasoningEffort(modelName).model;
|
|
33
|
+
}
|
|
34
|
+
__name(normalizeOpenAIModelName, "normalizeOpenAIModelName");
|
|
6
35
|
function isEmbeddingModel(modelName) {
|
|
7
36
|
return modelName.includes("embed") || modelName.includes("bge") || modelName.includes("instructor-large") || modelName.includes("m3e");
|
|
8
37
|
}
|
|
@@ -21,7 +50,7 @@ function getModelMaxContextSize(info) {
|
|
|
21
50
|
if (maxTokens != null) {
|
|
22
51
|
return maxTokens;
|
|
23
52
|
}
|
|
24
|
-
const modelName = info.name;
|
|
53
|
+
const modelName = normalizeOpenAIModelName(info.name);
|
|
25
54
|
if (modelName.startsWith("gpt") || modelName.startsWith("o1") || modelName.startsWith("o3") || modelName.startsWith("o4")) {
|
|
26
55
|
return getModelContextSize(modelName);
|
|
27
56
|
}
|
|
@@ -83,7 +112,7 @@ var imageModelMatchers = [
|
|
|
83
112
|
"grok-4"
|
|
84
113
|
].map((pattern) => createGlobMatcher(pattern));
|
|
85
114
|
function supportImageInput(modelName) {
|
|
86
|
-
const lowerModel = modelName.toLowerCase();
|
|
115
|
+
const lowerModel = normalizeOpenAIModelName(modelName).toLowerCase();
|
|
87
116
|
return imageModelMatchers.some((matcher) => matcher(lowerModel));
|
|
88
117
|
}
|
|
89
118
|
__name(supportImageInput, "supportImageInput");
|
|
@@ -113,7 +142,8 @@ import {
|
|
|
113
142
|
import { isZodSchemaV3 } from "@langchain/core/utils/types";
|
|
114
143
|
async function langchainMessageToOpenAIMessage(messages, plugin, model, supportImageInput2, removeSystemMessage) {
|
|
115
144
|
const result = [];
|
|
116
|
-
const
|
|
145
|
+
const normalizedModel = model ? normalizeOpenAIModelName(model) : model;
|
|
146
|
+
const isDeepseekThinkModel = normalizedModel?.includes("deepseek-reasoner");
|
|
117
147
|
for (const rawMessage of messages) {
|
|
118
148
|
const role = messageTypeToOpenAIRole(rawMessage.getType());
|
|
119
149
|
const msg = {
|
|
@@ -143,25 +173,38 @@ async function langchainMessageToOpenAIMessage(messages, plugin, model, supportI
|
|
|
143
173
|
}
|
|
144
174
|
}
|
|
145
175
|
const images = rawMessage.additional_kwargs.images;
|
|
146
|
-
const lowerModel =
|
|
147
|
-
if ((lowerModel?.includes("vision") || lowerModel?.includes("gpt-4o") || lowerModel?.includes("claude") || lowerModel?.includes("gemini") || lowerModel?.includes("qwen-vl") || lowerModel?.includes("omni") || lowerModel?.includes("qwen2.5-vl") || lowerModel?.includes("qwen2.5-omni") || lowerModel?.includes("qwen-omni") || lowerModel?.includes("qwen2-vl") || lowerModel?.includes("qvq") ||
|
|
176
|
+
const lowerModel = normalizedModel?.toLowerCase() ?? "";
|
|
177
|
+
if ((lowerModel?.includes("vision") || lowerModel?.includes("gpt-4o") || lowerModel?.includes("claude") || lowerModel?.includes("gemini") || lowerModel?.includes("qwen-vl") || lowerModel?.includes("omni") || lowerModel?.includes("qwen2.5-vl") || lowerModel?.includes("qwen2.5-omni") || lowerModel?.includes("qwen-omni") || lowerModel?.includes("qwen2-vl") || lowerModel?.includes("qvq") || normalizedModel?.includes("o1") || normalizedModel?.includes("o4") || normalizedModel?.includes("o3") || normalizedModel?.includes("gpt-4.1") || normalizedModel?.includes("gpt-5") || supportImageInput2) && images != null) {
|
|
148
178
|
msg.content = [
|
|
149
179
|
{
|
|
150
180
|
type: "text",
|
|
151
181
|
text: rawMessage.content
|
|
152
182
|
}
|
|
153
183
|
];
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
184
|
+
const imageContents = await Promise.all(
|
|
185
|
+
images.map(async (image) => {
|
|
186
|
+
try {
|
|
187
|
+
const url = await fetchImageUrl(plugin, {
|
|
188
|
+
type: "image_url",
|
|
189
|
+
image_url: { url: image }
|
|
190
|
+
});
|
|
191
|
+
return {
|
|
192
|
+
type: "image_url",
|
|
193
|
+
image_url: {
|
|
194
|
+
url,
|
|
195
|
+
detail: "low"
|
|
196
|
+
}
|
|
197
|
+
};
|
|
198
|
+
} catch {
|
|
199
|
+
return null;
|
|
160
200
|
}
|
|
161
|
-
})
|
|
162
|
-
|
|
201
|
+
})
|
|
202
|
+
);
|
|
203
|
+
msg.content.push(
|
|
204
|
+
...imageContents.filter((content) => content != null)
|
|
205
|
+
);
|
|
163
206
|
} else if (Array.isArray(msg.content) && msg.content.length > 0) {
|
|
164
|
-
|
|
207
|
+
const mappedContent = await Promise.all(
|
|
165
208
|
msg.content.map(async (content) => {
|
|
166
209
|
if (!isMessageContentImageUrl(content)) return content;
|
|
167
210
|
try {
|
|
@@ -174,10 +217,11 @@ async function langchainMessageToOpenAIMessage(messages, plugin, model, supportI
|
|
|
174
217
|
}
|
|
175
218
|
};
|
|
176
219
|
} catch {
|
|
177
|
-
return
|
|
220
|
+
return null;
|
|
178
221
|
}
|
|
179
222
|
})
|
|
180
223
|
);
|
|
224
|
+
msg.content = mappedContent.filter((content) => content != null);
|
|
181
225
|
}
|
|
182
226
|
result.push(msg);
|
|
183
227
|
}
|
|
@@ -438,12 +482,14 @@ import { getMessageContent } from "koishi-plugin-chatluna/utils/string";
|
|
|
438
482
|
import { trackLogToLocal } from "koishi-plugin-chatluna/utils/logger";
|
|
439
483
|
import { deepAssign } from "koishi-plugin-chatluna/utils/object";
|
|
440
484
|
async function buildChatCompletionParams(params, plugin, enableGoogleSearch, supportImageInput2) {
|
|
485
|
+
const parsedModel = parseOpenAIModelNameWithReasoningEffort(params.model);
|
|
486
|
+
const normalizedModel = parsedModel.model;
|
|
441
487
|
const base = {
|
|
442
|
-
model:
|
|
488
|
+
model: normalizedModel,
|
|
443
489
|
messages: await langchainMessageToOpenAIMessage(
|
|
444
490
|
params.input,
|
|
445
491
|
plugin,
|
|
446
|
-
|
|
492
|
+
normalizedModel,
|
|
447
493
|
supportImageInput2
|
|
448
494
|
),
|
|
449
495
|
tools: enableGoogleSearch || params.tools != null ? formatToolsToOpenAITools(
|
|
@@ -451,20 +497,28 @@ async function buildChatCompletionParams(params, plugin, enableGoogleSearch, sup
|
|
|
451
497
|
enableGoogleSearch
|
|
452
498
|
) : void 0,
|
|
453
499
|
stop: params.stop || void 0,
|
|
454
|
-
max_tokens:
|
|
500
|
+
max_tokens: normalizedModel.includes("vision") ? void 0 : params.maxTokens,
|
|
455
501
|
temperature: params.temperature === 0 ? void 0 : params.temperature,
|
|
456
502
|
presence_penalty: params.presencePenalty === 0 ? void 0 : params.presencePenalty,
|
|
457
503
|
frequency_penalty: params.frequencyPenalty === 0 ? void 0 : params.frequencyPenalty,
|
|
458
504
|
n: params.n,
|
|
459
505
|
top_p: params.topP,
|
|
460
506
|
prompt_cache_key: params.id,
|
|
507
|
+
prompt_cache_retention: void 0,
|
|
508
|
+
prediction: void 0,
|
|
509
|
+
reasoning_effort: parsedModel.reasoningEffort,
|
|
510
|
+
response_format: void 0,
|
|
511
|
+
safety_identifier: void 0,
|
|
512
|
+
service_tier: void 0,
|
|
461
513
|
stream: true,
|
|
462
514
|
logit_bias: params.logitBias,
|
|
463
515
|
stream_options: {
|
|
464
516
|
include_usage: true
|
|
465
517
|
}
|
|
466
518
|
};
|
|
467
|
-
|
|
519
|
+
const lowerModel = normalizedModel.toLowerCase();
|
|
520
|
+
const isOpenAIReasoningModel = lowerModel.startsWith("o1") || lowerModel.startsWith("o3") || lowerModel.startsWith("o4") || lowerModel.startsWith("gpt-5");
|
|
521
|
+
if (isOpenAIReasoningModel) {
|
|
468
522
|
delete base.temperature;
|
|
469
523
|
delete base.presence_penalty;
|
|
470
524
|
delete base.frequency_penalty;
|
|
@@ -621,7 +675,7 @@ async function* completionStream(requestContext, params, completionUrl = "chat/c
|
|
|
621
675
|
const iterator = sseIterable(response);
|
|
622
676
|
yield* processStreamResponse(requestContext, iterator);
|
|
623
677
|
} catch (e) {
|
|
624
|
-
if (requestContext.ctx.chatluna.
|
|
678
|
+
if (requestContext.ctx.chatluna.currentConfig.isLog) {
|
|
625
679
|
await trackLogToLocal(
|
|
626
680
|
"Request",
|
|
627
681
|
JSON.stringify(chatCompletionParams),
|
|
@@ -655,7 +709,7 @@ async function completion(requestContext, params, completionUrl = "chat/completi
|
|
|
655
709
|
);
|
|
656
710
|
return await processResponse(requestContext, response);
|
|
657
711
|
} catch (e) {
|
|
658
|
-
if (requestContext.ctx.chatluna.
|
|
712
|
+
if (requestContext.ctx.chatluna.currentConfig.isLog) {
|
|
659
713
|
await trackLogToLocal(
|
|
660
714
|
"Request",
|
|
661
715
|
JSON.stringify(chatCompletionParams),
|
|
@@ -703,7 +757,37 @@ async function getModels(requestContext, config) {
|
|
|
703
757
|
);
|
|
704
758
|
data = await response.text();
|
|
705
759
|
data = JSON.parse(data);
|
|
706
|
-
|
|
760
|
+
const rawModels = data.data.map((model) => model.id);
|
|
761
|
+
const expanded = [];
|
|
762
|
+
const seen = /* @__PURE__ */ new Set();
|
|
763
|
+
const isOpenAIReasoningModel = /* @__PURE__ */ __name((model) => {
|
|
764
|
+
const lower = model.toLowerCase();
|
|
765
|
+
return lower.startsWith("gpt-5") || lower.startsWith("o1") || lower.startsWith("o3") || lower.startsWith("o4");
|
|
766
|
+
}, "isOpenAIReasoningModel");
|
|
767
|
+
const hasThinkingTag = /* @__PURE__ */ __name((model) => {
|
|
768
|
+
const lower = model.toLowerCase();
|
|
769
|
+
return lower.includes("thinking") || ["minimal", "low", "medium", "high", "xhigh"].some(
|
|
770
|
+
(level) => lower.includes(level)
|
|
771
|
+
);
|
|
772
|
+
}, "hasThinkingTag");
|
|
773
|
+
const push = /* @__PURE__ */ __name((model) => {
|
|
774
|
+
if (seen.has(model)) return;
|
|
775
|
+
seen.add(model);
|
|
776
|
+
expanded.push(model);
|
|
777
|
+
}, "push");
|
|
778
|
+
for (const model of rawModels) {
|
|
779
|
+
push(model);
|
|
780
|
+
if (!isOpenAIReasoningModel(model)) continue;
|
|
781
|
+
if (hasThinkingTag(model)) continue;
|
|
782
|
+
push(`${model}-non-thinking`);
|
|
783
|
+
push(`${model}`);
|
|
784
|
+
push(`${model}-minimal-thinking`);
|
|
785
|
+
push(`${model}-low-thinking`);
|
|
786
|
+
push(`${model}-medium-thinking`);
|
|
787
|
+
push(`${model}-high-thinking`);
|
|
788
|
+
push(`${model}-xhigh-thinking`);
|
|
789
|
+
}
|
|
790
|
+
return expanded;
|
|
707
791
|
} catch (e) {
|
|
708
792
|
if (e instanceof ChatLunaError) {
|
|
709
793
|
throw e;
|
|
@@ -735,6 +819,8 @@ export {
|
|
|
735
819
|
isNonLLMModel,
|
|
736
820
|
langchainMessageToOpenAIMessage,
|
|
737
821
|
messageTypeToOpenAIRole,
|
|
822
|
+
normalizeOpenAIModelName,
|
|
823
|
+
parseOpenAIModelNameWithReasoningEffort,
|
|
738
824
|
processDeepSeekThinkMessages,
|
|
739
825
|
processReasoningContent,
|
|
740
826
|
processResponse,
|
package/lib/requester.d.ts
CHANGED
|
@@ -25,6 +25,12 @@ export declare function buildChatCompletionParams(params: ModelRequestParams, pl
|
|
|
25
25
|
n: number;
|
|
26
26
|
top_p: number;
|
|
27
27
|
prompt_cache_key: string;
|
|
28
|
+
prompt_cache_retention: any;
|
|
29
|
+
prediction: any;
|
|
30
|
+
reasoning_effort: import("./client").OpenAIReasoningEffort;
|
|
31
|
+
response_format: any;
|
|
32
|
+
safety_identifier: any;
|
|
33
|
+
service_tier: any;
|
|
28
34
|
stream: boolean;
|
|
29
35
|
logit_bias: Record<string, number>;
|
|
30
36
|
stream_options: {
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@chatluna/v1-shared-adapter",
|
|
3
3
|
"description": "chatluna shared adapter",
|
|
4
|
-
"version": "1.0.
|
|
4
|
+
"version": "1.0.22",
|
|
5
5
|
"main": "lib/index.cjs",
|
|
6
6
|
"module": "lib/index.mjs",
|
|
7
7
|
"typings": "lib/index.d.ts",
|
|
@@ -36,16 +36,16 @@
|
|
|
36
36
|
"node": ">=18.0.0"
|
|
37
37
|
},
|
|
38
38
|
"resolutions": {
|
|
39
|
-
"@langchain/core": "0.3.
|
|
39
|
+
"@langchain/core": "^0.3.80",
|
|
40
40
|
"js-tiktoken": "npm:@dingyi222666/js-tiktoken@^1.0.21"
|
|
41
41
|
},
|
|
42
42
|
"overrides": {
|
|
43
|
-
"@langchain/core": "0.3.
|
|
43
|
+
"@langchain/core": "^0.3.80",
|
|
44
44
|
"js-tiktoken": "npm:@dingyi222666/js-tiktoken@^1.0.21"
|
|
45
45
|
},
|
|
46
46
|
"pnpm": {
|
|
47
47
|
"overrides": {
|
|
48
|
-
"@langchain/core": "0.3.
|
|
48
|
+
"@langchain/core": "^0.3.80",
|
|
49
49
|
"js-tiktoken": "npm:@dingyi222666/js-tiktoken@^1.0.21"
|
|
50
50
|
}
|
|
51
51
|
},
|
|
@@ -60,7 +60,7 @@
|
|
|
60
60
|
"adapter"
|
|
61
61
|
],
|
|
62
62
|
"dependencies": {
|
|
63
|
-
"@langchain/core": "0.3.
|
|
63
|
+
"@langchain/core": "^0.3.80",
|
|
64
64
|
"zod": "3.25.76",
|
|
65
65
|
"zod-to-json-schema": "^3.24.6"
|
|
66
66
|
},
|
|
@@ -70,6 +70,6 @@
|
|
|
70
70
|
},
|
|
71
71
|
"peerDependencies": {
|
|
72
72
|
"koishi": "^4.18.9",
|
|
73
|
-
"koishi-plugin-chatluna": "^1.3.
|
|
73
|
+
"koishi-plugin-chatluna": "^1.3.14"
|
|
74
74
|
}
|
|
75
75
|
}
|