Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
87 changes: 57 additions & 30 deletions packages/adapter-gemini/src/client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,8 @@ import { RunnableConfig } from '@langchain/core/runnables'
import { GeminiModelInfo } from './types'
import {
createGeminiCapabilities,
expandModelVariants,
getModelVariantSuffixes,
isGeminiModelName,
shouldFilterOutGeminiModel
} from './utils'

Expand Down Expand Up @@ -115,20 +116,18 @@ export class GeminiClient extends PlatformModelAndEmbeddingsClient<ClientConfig>
// #region refreshModels

/**
* 从 API 获取模型列表,并将每个模型展开为对应的所有变体:
* - 图片生成模型:分辨率 + 搜索后缀变体
* - gemini-2.5 系列:-thinking / -non-thinking 变体
* - gemini-3 系列:thinking 等级变体(low / medium / high / minimal)
* - 其他模型:直接加入,不展开
* 从配置与 API 获取模型列表,并将特定系列展开为变体
* (图片分辨率 / 搜索后缀、thinking 开关与等级)。
*/
async refreshModels(config?: RunnableConfig): Promise<ModelInfo[]> {
// --- 获取原始模型列表 ---
let rawModels: GeminiModelInfo[] = []

try {
rawModels = await this._requester.getModels(config)
rawModels = this._config.pullModels
? await this._requester.getModels(config)
: []
Comment thread
dingyi222666 marked this conversation as resolved.

if (rawModels.length === 0) {
if (this._config.pullModels && rawModels.length === 0) {
Comment thread
dingyi222666 marked this conversation as resolved.
throw new ChatLunaError(
ChatLunaErrorCode.MODEL_INIT_ERROR,
new Error('No model found')
Expand All @@ -139,38 +138,66 @@ export class GeminiClient extends PlatformModelAndEmbeddingsClient<ClientConfig>
throw new ChatLunaError(ChatLunaErrorCode.MODEL_INIT_ERROR, e)
}

// --- 将原始模型转换并展开为变体列表 ---
const models: ModelInfo[] = []
const items: ModelInfo[] = this._config.additionalModels.map(
(model) => {
const name = model.model.toLowerCase()
const isEmbedding = model.modelType === 'Embeddings 嵌入模型'

return {
name: model.model,
maxTokens: model.contextSize,
type: isEmbedding ? ModelType.embeddings : ModelType.llm,
capabilities: isEmbedding
? []
: isGeminiModelName(name)
? createGeminiCapabilities(name, false)
: model.modelCapabilities
}
}
)

for (const model of rawModels) {
const modelNameLower = model.name.toLowerCase()
const name = model.name.toLowerCase()

if (shouldFilterOutGeminiModel(modelNameLower)) {
continue
}
if (shouldFilterOutGeminiModel(name)) continue

const isEmbedding = modelNameLower.includes('embedding')
const isEmbedding = name.includes('embedding')

const baseInfo: ModelInfo = {
items.push({
name: model.name,
maxTokens: model.inputTokenLimit,
type: isEmbedding ? ModelType.embeddings : ModelType.llm,
capabilities: createGeminiCapabilities(
modelNameLower,
isEmbedding
)
capabilities: createGeminiCapabilities(name, isEmbedding)
})
}

const models: ModelInfo[] = []
const names = new Set<string>()
const addModel = (model: ModelInfo) => {
const key = model.name.toLowerCase()
if (!names.has(key)) {
names.add(key)
models.push(model)
}
}

// 尝试展开特殊变体;未命中则直接加入
if (
!expandModelVariants(
models,
baseInfo,
this._config.imageModelSearch
)
) {
models.push(baseInfo)
for (const model of items) {
const suffixes = getModelVariantSuffixes(
model.name.toLowerCase(),
this._config.imageModelSearch
)

for (const suffix of suffixes) {
addModel({ ...model, name: model.name + suffix })
}
addModel(model)
}

if (models.length === 0) {
throw new ChatLunaError(
ChatLunaErrorCode.MODEL_INIT_ERROR,
new Error('No model configured')
)
}

return models
Comment thread
dingyi222666 marked this conversation as resolved.
Expand Down
37 changes: 37 additions & 0 deletions packages/adapter-gemini/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { ChatLunaPlugin } from 'koishi-plugin-chatluna/services/chat'
import { Context, Logger, Schema } from 'koishi'
import { GeminiClient } from './client'
import { createLogger } from 'koishi-plugin-chatluna/utils/logger'
import { ModelCapabilities } from 'koishi-plugin-chatluna/llm-core/platform/types'

export let logger: Logger
export const reusable = true
Expand Down Expand Up @@ -38,6 +39,13 @@ export function apply(ctx: Context, config: Config) {

export interface Config extends ChatLunaPlugin.Config {
apiKeys: [string, string, boolean][]
pullModels: boolean
additionalModels: {
model: string
modelType: string
modelCapabilities: ModelCapabilities[]
contextSize: number
}[]
maxContextRatio: number
platform: string
temperature: number
Expand All @@ -58,6 +66,35 @@ export const Config: Schema<Config> = Schema.intersect([
ChatLunaPlugin.Config,
Schema.object({
platform: Schema.string().default('gemini'),
pullModels: Schema.boolean().default(true),
additionalModels: Schema.array(
Schema.object({
model: Schema.string(),
modelType: Schema.union([
'LLM 大语言模型',
'Embeddings 嵌入模型'
]).default('LLM 大语言模型'),
Comment thread
dingyi222666 marked this conversation as resolved.
modelCapabilities: Schema.array(
Schema.union([
ModelCapabilities.TextInput,
ModelCapabilities.ToolCall,
ModelCapabilities.ImageInput,
ModelCapabilities.ImageGeneration,
ModelCapabilities.AudioInput,
ModelCapabilities.VideoInput,
ModelCapabilities.FileInput
])
)
.default([
ModelCapabilities.TextInput,
ModelCapabilities.ToolCall
])
.role('checkbox'),
contextSize: Schema.number().default(128000)
})
)
.default([])
.role('table'),
apiKeys: Schema.array(
Schema.tuple([
Schema.string().role('secret').default(''),
Expand Down
17 changes: 17 additions & 0 deletions packages/adapter-gemini/src/locales/en-US.schema.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,23 @@ $inner:
- {}
- $desc: 'API Configuration'
platform: 'Adapter platform name. (Do not modify if you do not understand)'
pullModels: 'Auto-fetch model list. If disabled, use only specified models.'
additionalModels:
$desc: 'Additional model list.'
$inner:
model: 'Model name.'
modelType: 'Model type.'
contextSize: 'Context size.'
modelCapabilities:
$desc: 'Model capabilities.'
$inner:
- 'Text input'
- 'Tool calling'
- 'Visual image input'
- 'Image generation'
- 'Audio input'
- 'Video input'
- 'File input'
apiKeys:
$inner:
- 'Gemini API Key'
Expand Down
17 changes: 17 additions & 0 deletions packages/adapter-gemini/src/locales/zh-CN.schema.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,23 @@ $inner:
- {}
- $desc: '请求选项'
platform: '适配器的平台名。(不懂请不要修改)'
pullModels: '是否自动拉取模型列表。关闭后将仅使用下方指定的模型。'
additionalModels:
$desc: '额外模型列表。'
$inner:
model: '模型名称。'
modelType: '模型类型。'
contextSize: '模型上下文大小。'
modelCapabilities:
$desc: '模型支持的能力。'
$inner:
- '文本输入'
- '工具调用'
- '图片视觉输入'
- '图像生成'
- '音频输入'
- '视频输入'
- '文件输入'
apiKeys:
$inner:
- 'Gemini API Key'
Expand Down
Loading
Loading