koishi-plugin-chatluna-google-gemini-adapter 1.3.4 → 1.3.5

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/index.cjs CHANGED
@@ -46,7 +46,7 @@ __export(index_exports, {
46
46
  });
47
47
  module.exports = __toCommonJS(index_exports);
48
48
  var import_chat = require("koishi-plugin-chatluna/services/chat");
49
- var import_koishi = require("koishi");
49
+ var import_koishi2 = require("koishi");
50
50
 
51
51
  // src/client.ts
52
52
  var import_client = require("koishi-plugin-chatluna/llm-core/platform/client");
@@ -67,6 +67,7 @@ var import_v1_shared_adapter = require("@chatluna/v1-shared-adapter");
67
67
  var import_string = require("koishi-plugin-chatluna/utils/string");
68
68
  var import_types = require("@langchain/core/utils/types");
69
69
  var import_zod_openapi = require("@anatine/zod-openapi");
70
+ var import_koishi = require("koishi");
70
71
  async function langchainMessageToGeminiMessage(messages, plugin, model) {
71
72
  return Promise.all(
72
73
  messages.map(async (message) => {
@@ -264,11 +265,7 @@ function formatToolsToGeminiAITools(tools, config, model) {
264
265
  urlContext = false;
265
266
  }
266
267
  if (googleSearch) {
267
- if (model.includes("gemini-2")) {
268
- result.push({
269
- google_search: {}
270
- });
271
- } else {
268
+ if (model.includes("gemini-1")) {
272
269
  result.push({
273
270
  google_search_retrieval: {
274
271
  dynamic_retrieval_config: {
@@ -277,6 +274,10 @@ function formatToolsToGeminiAITools(tools, config, model) {
277
274
  }
278
275
  }
279
276
  });
277
+ } else {
278
+ result.push({
279
+ google_search: {}
280
+ });
280
281
  }
281
282
  }
282
283
  if (codeExecution) {
@@ -322,6 +323,7 @@ __name(messageTypeToGeminiRole, "messageTypeToGeminiRole");
322
323
  function prepareModelConfig(params, pluginConfig) {
323
324
  let model = params.model;
324
325
  let enabledThinking = null;
326
+ let thinkingLevel = "high";
325
327
  if (model.includes("-thinking") && model.includes("gemini-2.5")) {
326
328
  enabledThinking = !model.includes("-non-thinking");
327
329
  model = model.replace("-non-thinking", "").replace("-thinking", "");
@@ -332,35 +334,53 @@ function prepareModelConfig(params, pluginConfig) {
332
334
  } else if (thinkingBudget >= 0 && thinkingBudget < 128) {
333
335
  thinkingBudget = 128;
334
336
  }
337
+ if (model.includes("-thinking") && model.includes("gemini-3.0")) {
338
+ enabledThinking = true;
339
+ const match = model.match(/-(low|medium|high)-thinking/);
340
+ if (match) {
341
+ thinkingLevel = match[1];
342
+ model = model.replace(`-${match[1]}-thinking`, "");
343
+ } else {
344
+ thinkingLevel = "low";
345
+ model = model.replace("-thinking", "");
346
+ }
347
+ thinkingBudget = void 0;
348
+ }
335
349
  let imageGeneration = pluginConfig.imageGeneration ?? false;
336
350
  if (imageGeneration) {
337
351
  imageGeneration = params.model.includes("gemini-2.0-flash-exp") || params.model.includes("gemini-2.5-flash-image");
338
352
  }
339
- return { model, enabledThinking, thinkingBudget, imageGeneration };
353
+ return {
354
+ model,
355
+ enabledThinking,
356
+ thinkingBudget,
357
+ imageGeneration,
358
+ thinkingLevel
359
+ };
340
360
  }
341
361
  __name(prepareModelConfig, "prepareModelConfig");
342
362
  function createSafetySettings(model) {
343
- const isGemini2 = model.includes("gemini-2");
363
+ const isNonGemini1 = !model.includes("gemini-1");
344
364
  return [
345
365
  {
346
366
  category: "HARM_CATEGORY_HARASSMENT",
347
- threshold: isGemini2 ? "OFF" : "BLOCK_NONE"
367
+ threshold: isNonGemini1 ? "OFF" : "BLOCK_NONE"
348
368
  },
349
369
  {
350
370
  category: "HARM_CATEGORY_HATE_SPEECH",
351
- threshold: isGemini2 ? "OFF" : "BLOCK_NONE"
371
+ threshold: isNonGemini1 ? "OFF" : "BLOCK_NONE"
352
372
  },
353
373
  {
354
374
  category: "HARM_CATEGORY_SEXUALLY_EXPLICIT",
355
- threshold: isGemini2 ? "OFF" : "BLOCK_NONE"
375
+ threshold: isNonGemini1 ? "OFF" : "BLOCK_NONE"
356
376
  },
357
377
  {
358
378
  category: "HARM_CATEGORY_DANGEROUS_CONTENT",
359
- threshold: isGemini2 ? "OFF" : "BLOCK_NONE"
379
+ threshold: isNonGemini1 ? "OFF" : "BLOCK_NONE"
360
380
  },
361
381
  {
362
382
  category: "HARM_CATEGORY_CIVIC_INTEGRITY",
363
- threshold: isGemini2 ? "OFF" : "BLOCK_NONE"
383
+ threshold: isNonGemini1 ? "OFF" : "BLOCK_NONE"
364
384
  }
365
385
  ];
366
386
  }
@@ -372,10 +392,14 @@ function createGenerationConfig(params, modelConfig, pluginConfig) {
372
392
  maxOutputTokens: params.model.includes("vision") ? void 0 : params.maxTokens,
373
393
  topP: params.topP,
374
394
  responseModalities: modelConfig.imageGeneration ? ["TEXT", "IMAGE"] : void 0,
375
- thinkingConfig: modelConfig.enabledThinking != null || pluginConfig.includeThoughts ? {
376
- thinkingBudget: modelConfig.thinkingBudget,
377
- includeThoughts: pluginConfig.includeThoughts
378
- } : void 0
395
+ thinkingConfig: modelConfig.enabledThinking != null || pluginConfig.includeThoughts ? (0, import_koishi.filterKeys)(
396
+ {
397
+ thinkingBudget: modelConfig.thinkingBudget,
398
+ thinkingLevel: modelConfig.thinkingLevel,
399
+ includeThoughts: pluginConfig.includeThoughts
400
+ },
401
+ (k, v) => v != null
402
+ ) : void 0
379
403
  };
380
404
  }
381
405
  __name(createGenerationConfig, "createGenerationConfig");
@@ -980,11 +1004,8 @@ var GeminiClient = class extends import_client.PlatformModelAndEmbeddingsClient
980
1004
  import_types2.ModelCapabilities.ToolCall
981
1005
  ]
982
1006
  };
983
- const thinkingModel = [
984
- "gemini-2.5-pro",
985
- "gemini-2.5-flash",
986
- "gemini-3.0-pro"
987
- ];
1007
+ const thinkingModel = ["gemini-2.5-pro", "gemini-2.5-flash"];
1008
+ const thinkingLevelModel = ["gemini-3.0-pro"];
988
1009
  if (thinkingModel.some(
989
1010
  (name2) => model.name.toLowerCase().includes(name2) && !model.name.toLowerCase().includes("image")
990
1011
  )) {
@@ -997,6 +1018,13 @@ var GeminiClient = class extends import_client.PlatformModelAndEmbeddingsClient
997
1018
  } else {
998
1019
  models.push(info);
999
1020
  }
1021
+ } else if (thinkingLevelModel.some(
1022
+ (name2) => model.name.toLowerCase().includes(name2) && !model.name.toLowerCase().includes("image")
1023
+ )) {
1024
+ models.push(
1025
+ { ...info, name: model.name + "-low-thinking" },
1026
+ info
1027
+ );
1000
1028
  } else {
1001
1029
  models.push(info);
1002
1030
  }
@@ -1065,32 +1093,32 @@ function apply(ctx, config) {
1065
1093
  });
1066
1094
  }
1067
1095
  __name(apply, "apply");
1068
- var Config4 = import_koishi.Schema.intersect([
1096
+ var Config4 = import_koishi2.Schema.intersect([
1069
1097
  import_chat.ChatLunaPlugin.Config,
1070
- import_koishi.Schema.object({
1071
- platform: import_koishi.Schema.string().default("gemini"),
1072
- apiKeys: import_koishi.Schema.array(
1073
- import_koishi.Schema.tuple([
1074
- import_koishi.Schema.string().role("secret").default(""),
1075
- import_koishi.Schema.string().default(
1098
+ import_koishi2.Schema.object({
1099
+ platform: import_koishi2.Schema.string().default("gemini"),
1100
+ apiKeys: import_koishi2.Schema.array(
1101
+ import_koishi2.Schema.tuple([
1102
+ import_koishi2.Schema.string().role("secret").default(""),
1103
+ import_koishi2.Schema.string().default(
1076
1104
  "https://generativelanguage.googleapis.com/v1beta"
1077
1105
  ),
1078
- import_koishi.Schema.boolean().default(true)
1106
+ import_koishi2.Schema.boolean().default(true)
1079
1107
  ])
1080
1108
  ).default([[]]).role("table")
1081
1109
  }),
1082
- import_koishi.Schema.object({
1083
- maxContextRatio: import_koishi.Schema.number().min(0).max(1).step(1e-4).role("slider").default(0.35),
1084
- temperature: import_koishi.Schema.percent().min(0).max(2).step(0.1).default(1),
1085
- googleSearch: import_koishi.Schema.boolean().default(false),
1086
- codeExecution: import_koishi.Schema.boolean().default(false),
1087
- urlContext: import_koishi.Schema.boolean().default(false),
1088
- thinkingBudget: import_koishi.Schema.number().min(-1).max(24576).default(-1),
1089
- includeThoughts: import_koishi.Schema.boolean().default(false),
1090
- nonStreaming: import_koishi.Schema.boolean().default(false),
1091
- imageGeneration: import_koishi.Schema.boolean().default(false),
1092
- groundingContentDisplay: import_koishi.Schema.boolean().default(false),
1093
- searchThreshold: import_koishi.Schema.number().min(0).max(1).step(0.1).default(0.5)
1110
+ import_koishi2.Schema.object({
1111
+ maxContextRatio: import_koishi2.Schema.number().min(0).max(1).step(1e-4).role("slider").default(0.35),
1112
+ temperature: import_koishi2.Schema.percent().min(0).max(2).step(0.1).default(1),
1113
+ googleSearch: import_koishi2.Schema.boolean().default(false),
1114
+ codeExecution: import_koishi2.Schema.boolean().default(false),
1115
+ urlContext: import_koishi2.Schema.boolean().default(false),
1116
+ thinkingBudget: import_koishi2.Schema.number().min(-1).max(24576).default(-1),
1117
+ includeThoughts: import_koishi2.Schema.boolean().default(false),
1118
+ nonStreaming: import_koishi2.Schema.boolean().default(false),
1119
+ imageGeneration: import_koishi2.Schema.boolean().default(false),
1120
+ groundingContentDisplay: import_koishi2.Schema.boolean().default(false),
1121
+ searchThreshold: import_koishi2.Schema.number().min(0).max(1).step(0.1).default(0.5)
1094
1122
  })
1095
1123
  ]).i18n({
1096
1124
  "zh-CN": require_zh_CN_schema(),
package/lib/index.mjs CHANGED
@@ -64,6 +64,7 @@ import {
64
64
  } from "koishi-plugin-chatluna/utils/string";
65
65
  import { isZodSchemaV3 } from "@langchain/core/utils/types";
66
66
  import { generateSchema } from "@anatine/zod-openapi";
67
+ import { filterKeys } from "koishi";
67
68
  async function langchainMessageToGeminiMessage(messages, plugin, model) {
68
69
  return Promise.all(
69
70
  messages.map(async (message) => {
@@ -261,11 +262,7 @@ function formatToolsToGeminiAITools(tools, config, model) {
261
262
  urlContext = false;
262
263
  }
263
264
  if (googleSearch) {
264
- if (model.includes("gemini-2")) {
265
- result.push({
266
- google_search: {}
267
- });
268
- } else {
265
+ if (model.includes("gemini-1")) {
269
266
  result.push({
270
267
  google_search_retrieval: {
271
268
  dynamic_retrieval_config: {
@@ -274,6 +271,10 @@ function formatToolsToGeminiAITools(tools, config, model) {
274
271
  }
275
272
  }
276
273
  });
274
+ } else {
275
+ result.push({
276
+ google_search: {}
277
+ });
277
278
  }
278
279
  }
279
280
  if (codeExecution) {
@@ -319,6 +320,7 @@ __name(messageTypeToGeminiRole, "messageTypeToGeminiRole");
319
320
  function prepareModelConfig(params, pluginConfig) {
320
321
  let model = params.model;
321
322
  let enabledThinking = null;
323
+ let thinkingLevel = "high";
322
324
  if (model.includes("-thinking") && model.includes("gemini-2.5")) {
323
325
  enabledThinking = !model.includes("-non-thinking");
324
326
  model = model.replace("-non-thinking", "").replace("-thinking", "");
@@ -329,35 +331,53 @@ function prepareModelConfig(params, pluginConfig) {
329
331
  } else if (thinkingBudget >= 0 && thinkingBudget < 128) {
330
332
  thinkingBudget = 128;
331
333
  }
334
+ if (model.includes("-thinking") && model.includes("gemini-3.0")) {
335
+ enabledThinking = true;
336
+ const match = model.match(/-(low|medium|high)-thinking/);
337
+ if (match) {
338
+ thinkingLevel = match[1];
339
+ model = model.replace(`-${match[1]}-thinking`, "");
340
+ } else {
341
+ thinkingLevel = "low";
342
+ model = model.replace("-thinking", "");
343
+ }
344
+ thinkingBudget = void 0;
345
+ }
332
346
  let imageGeneration = pluginConfig.imageGeneration ?? false;
333
347
  if (imageGeneration) {
334
348
  imageGeneration = params.model.includes("gemini-2.0-flash-exp") || params.model.includes("gemini-2.5-flash-image");
335
349
  }
336
- return { model, enabledThinking, thinkingBudget, imageGeneration };
350
+ return {
351
+ model,
352
+ enabledThinking,
353
+ thinkingBudget,
354
+ imageGeneration,
355
+ thinkingLevel
356
+ };
337
357
  }
338
358
  __name(prepareModelConfig, "prepareModelConfig");
339
359
  function createSafetySettings(model) {
340
- const isGemini2 = model.includes("gemini-2");
360
+ const isNonGemini1 = !model.includes("gemini-1");
341
361
  return [
342
362
  {
343
363
  category: "HARM_CATEGORY_HARASSMENT",
344
- threshold: isGemini2 ? "OFF" : "BLOCK_NONE"
364
+ threshold: isNonGemini1 ? "OFF" : "BLOCK_NONE"
345
365
  },
346
366
  {
347
367
  category: "HARM_CATEGORY_HATE_SPEECH",
348
- threshold: isGemini2 ? "OFF" : "BLOCK_NONE"
368
+ threshold: isNonGemini1 ? "OFF" : "BLOCK_NONE"
349
369
  },
350
370
  {
351
371
  category: "HARM_CATEGORY_SEXUALLY_EXPLICIT",
352
- threshold: isGemini2 ? "OFF" : "BLOCK_NONE"
372
+ threshold: isNonGemini1 ? "OFF" : "BLOCK_NONE"
353
373
  },
354
374
  {
355
375
  category: "HARM_CATEGORY_DANGEROUS_CONTENT",
356
- threshold: isGemini2 ? "OFF" : "BLOCK_NONE"
376
+ threshold: isNonGemini1 ? "OFF" : "BLOCK_NONE"
357
377
  },
358
378
  {
359
379
  category: "HARM_CATEGORY_CIVIC_INTEGRITY",
360
- threshold: isGemini2 ? "OFF" : "BLOCK_NONE"
380
+ threshold: isNonGemini1 ? "OFF" : "BLOCK_NONE"
361
381
  }
362
382
  ];
363
383
  }
@@ -369,10 +389,14 @@ function createGenerationConfig(params, modelConfig, pluginConfig) {
369
389
  maxOutputTokens: params.model.includes("vision") ? void 0 : params.maxTokens,
370
390
  topP: params.topP,
371
391
  responseModalities: modelConfig.imageGeneration ? ["TEXT", "IMAGE"] : void 0,
372
- thinkingConfig: modelConfig.enabledThinking != null || pluginConfig.includeThoughts ? {
373
- thinkingBudget: modelConfig.thinkingBudget,
374
- includeThoughts: pluginConfig.includeThoughts
375
- } : void 0
392
+ thinkingConfig: modelConfig.enabledThinking != null || pluginConfig.includeThoughts ? filterKeys(
393
+ {
394
+ thinkingBudget: modelConfig.thinkingBudget,
395
+ thinkingLevel: modelConfig.thinkingLevel,
396
+ includeThoughts: pluginConfig.includeThoughts
397
+ },
398
+ (k, v) => v != null
399
+ ) : void 0
376
400
  };
377
401
  }
378
402
  __name(createGenerationConfig, "createGenerationConfig");
@@ -977,11 +1001,8 @@ var GeminiClient = class extends PlatformModelAndEmbeddingsClient {
977
1001
  ModelCapabilities.ToolCall
978
1002
  ]
979
1003
  };
980
- const thinkingModel = [
981
- "gemini-2.5-pro",
982
- "gemini-2.5-flash",
983
- "gemini-3.0-pro"
984
- ];
1004
+ const thinkingModel = ["gemini-2.5-pro", "gemini-2.5-flash"];
1005
+ const thinkingLevelModel = ["gemini-3.0-pro"];
985
1006
  if (thinkingModel.some(
986
1007
  (name2) => model.name.toLowerCase().includes(name2) && !model.name.toLowerCase().includes("image")
987
1008
  )) {
@@ -994,6 +1015,13 @@ var GeminiClient = class extends PlatformModelAndEmbeddingsClient {
994
1015
  } else {
995
1016
  models.push(info);
996
1017
  }
1018
+ } else if (thinkingLevelModel.some(
1019
+ (name2) => model.name.toLowerCase().includes(name2) && !model.name.toLowerCase().includes("image")
1020
+ )) {
1021
+ models.push(
1022
+ { ...info, name: model.name + "-low-thinking" },
1023
+ info
1024
+ );
997
1025
  } else {
998
1026
  models.push(info);
999
1027
  }
package/lib/utils.d.ts CHANGED
@@ -16,6 +16,7 @@ export declare function prepareModelConfig(params: ModelRequestParams, pluginCon
16
16
  enabledThinking: boolean;
17
17
  thinkingBudget: number;
18
18
  imageGeneration: boolean;
19
+ thinkingLevel: string;
19
20
  };
20
21
  export declare function createSafetySettings(model: string): {
21
22
  category: string;
@@ -27,10 +28,7 @@ export declare function createGenerationConfig(params: ModelRequestParams, model
27
28
  maxOutputTokens: number;
28
29
  topP: number;
29
30
  responseModalities: string[];
30
- thinkingConfig: {
31
- thinkingBudget: number;
32
- includeThoughts: boolean;
33
- };
31
+ thinkingConfig: import("cosmokit").Dict<string | number | boolean, "thinkingBudget" | "thinkingLevel" | "includeThoughts">;
34
32
  };
35
33
  export declare function createChatGenerationParams(params: ModelRequestParams, plugin: ChatLunaPlugin, modelConfig: ReturnType<typeof prepareModelConfig>, pluginConfig: Config): Promise<{
36
34
  contents: ChatCompletionResponseMessage[];
@@ -44,10 +42,7 @@ export declare function createChatGenerationParams(params: ModelRequestParams, p
44
42
  maxOutputTokens: number;
45
43
  topP: number;
46
44
  responseModalities: string[];
47
- thinkingConfig: {
48
- thinkingBudget: number;
49
- includeThoughts: boolean;
50
- };
45
+ thinkingConfig: import("cosmokit").Dict<string | number | boolean, "thinkingBudget" | "thinkingLevel" | "includeThoughts">;
51
46
  };
52
47
  system_instruction: ChatCompletionResponseMessage;
53
48
  tools: Record<string, any>;
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "koishi-plugin-chatluna-google-gemini-adapter",
3
3
  "description": "google-gemini adapter for chatluna",
4
- "version": "1.3.4",
4
+ "version": "1.3.5",
5
5
  "main": "lib/index.cjs",
6
6
  "module": "lib/index.mjs",
7
7
  "typings": "lib/index.d.ts",