Skip to content

Commit f857957

Browse files
authored
Merge pull request #71 from CookSleep/feat/tool-call-reply-config
支持按会话配置工具调用回复字段
2 parents 34468d9 + d93fa9f commit f857957

5 files changed

Lines changed: 229 additions & 124 deletions

File tree

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"name": "koishi-plugin-chatluna-character",
33
"description": "Let the large language model play a role, disguise as a group friend",
4-
"version": "0.0.209",
4+
"version": "0.0.210",
55
"type": "module",
66
"main": "lib/index.cjs",
77
"module": "lib/index.mjs",

src/config.ts

Lines changed: 100 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,10 @@ export interface Config extends ChatLunaPlugin.Config {
4848

4949
toolCalling: boolean
5050
experimentalToolCallReply: boolean
51+
toolCallReplyThinkTag: boolean
52+
toolCallReplyStatusTag: boolean
53+
toolCallReplyNextReply: boolean
54+
toolCallReplyWakeUpReply: boolean
5155
isForceMute: boolean
5256
sendStickerProbability: number
5357
image: boolean
@@ -109,8 +113,8 @@ const commonModelConfig = Schema.object({
109113
.default(true)
110114
.description(
111115
'是否在缺失历史消息时自动从支持的 API ' +
112-
'(如 OneBot 及所有支持 getMessageList 的适配器)' +
113-
'获取历史消息,使重启插件时可以获取刚刚的上下文'
116+
'(如 OneBot 及所有支持 getMessageList 的适配器)' +
117+
'获取历史消息,使重启插件时可以获取刚刚的上下文'
114118
)
115119
})
116120
.description('上下文')
@@ -150,40 +154,73 @@ const commonMuteConfig = Schema.object({
150154
.description('闭嘴')
151155
.collapse()
152156

153-
const commonModelFeatureConfig = Schema.object({
154-
toolCalling: Schema.boolean()
157+
const commonToolCallReplyConfig = Schema.object({
158+
experimentalToolCallReply: Schema.boolean()
159+
.default(false)
155160
.description(
156-
'是否启用工具调用功能(可在[**这里**]' +
157-
'(https://cooksleep.github.io/newapi-special-test)' +
158-
'测试你的 API 工具调用等能力是否正常)'
159-
)
160-
.default(true),
161-
image: Schema.boolean()
161+
'是否启用实验性“工具调用回复”功能(需同时开启“工具调用”,让模型通过工具调用完成状态更新、回复消息等原本依赖 XML 块的操作,在使用前请先查看文档)'
162+
),
163+
toolCallReplyThinkTag: Schema.boolean()
164+
.default(true)
162165
.description(
163-
'是否允许输入图片(注意表情包也会输入,目前仅支持原生多模态的模型)'
164-
)
165-
.default(false),
166-
imageInputMaxCount: Schema.number()
167-
.default(9)
168-
.min(1)
169-
.max(15)
170-
.description('最大的输入图片数量'),
171-
imageInputMaxSize: Schema.number()
172-
.default(20)
173-
.min(1)
174-
.max(100)
175-
.description('最大的输入图片大小(MB)'),
176-
multimodalFileInputMaxSize: Schema.number()
177-
.default(20)
178-
.min(1)
179-
.max(100)
166+
'是否启用 `<think>` 标签(使模型进行角色扮演式“思考”,展示角色的心路历程,主要起到观赏性作用)'
167+
),
168+
toolCallReplyStatusTag: Schema.boolean()
169+
.default(true)
170+
.description(
171+
'是否启用 `<status>` 标签(使模型可以临时性记忆更多上下文、维护自身状态信息,可以有效提升角色扮演效果)'
172+
),
173+
toolCallReplyNextReply: Schema.boolean()
174+
.default(true)
180175
.description(
181-
'最大的多模态文件输入大小(MB):过大可能造成服务器卡顿、回复延迟'
176+
'是否启用 `next_reply`(使模型可以设置下一次短期主动触发条件)'
177+
),
178+
toolCallReplyWakeUpReply: Schema.boolean()
179+
.default(true)
180+
.description(
181+
'是否启用 `wake_up_reply`(使模型可以设置未来某个时间点的主动触发条件)'
182182
)
183183
})
184-
.description('工具与多模态')
184+
.description('工具调用回复')
185185
.collapse()
186186

187+
const commonModelFeatureConfig = Schema.intersect([
188+
Schema.object({
189+
toolCalling: Schema.boolean()
190+
.description(
191+
'是否启用工具调用功能(可在[**这里**]' +
192+
'(https://cooksleep.github.io/newapi-special-test)' +
193+
'测试你的 API 工具调用等能力是否正常)'
194+
)
195+
.default(true),
196+
image: Schema.boolean()
197+
.description(
198+
'是否允许输入图片(注意表情包也会输入,目前仅支持原生多模态的模型)'
199+
)
200+
.default(false),
201+
imageInputMaxCount: Schema.number()
202+
.default(9)
203+
.min(1)
204+
.max(15)
205+
.description('最大的输入图片数量'),
206+
imageInputMaxSize: Schema.number()
207+
.default(20)
208+
.min(1)
209+
.max(100)
210+
.description('最大的输入图片大小(MB)'),
211+
multimodalFileInputMaxSize: Schema.number()
212+
.default(20)
213+
.min(1)
214+
.max(100)
215+
.description(
216+
'最大的多模态文件输入大小(MB):过大可能造成服务器卡顿、回复延迟'
217+
)
218+
})
219+
.description('工具与多模态')
220+
.collapse(),
221+
commonToolCallReplyConfig
222+
])
223+
187224
const privateIdleConfig = Schema.object({
188225
enableLongWaitTrigger: Schema.boolean()
189226
.default(false)
@@ -551,12 +588,7 @@ export const Config = Schema.intersect([
551588
).description('启用此插件时,不禁用 ChatLuna 主功能的私聊用户 ID 列表'),
552589
whiteListDisableChatLuna: Schema.array(Schema.string()).description(
553590
'启用此插件时,不禁用 ChatLuna 主功能的群聊 ID 列表'
554-
),
555-
experimentalToolCallReply: Schema.boolean()
556-
.default(false)
557-
.description(
558-
'是否启用实验性“工具调用回复”功能(需同时开启“工具调用”,让模型通过工具调用完成状态更新、回复消息等原本依赖 XML 块的操作)'
559-
)
591+
)
560592
})
561593
.description('基础配置')
562594
.collapse(),
@@ -604,6 +636,7 @@ type LegacyConfig = Config & {
604636
imageInputMaxSize?: number
605637
multimodalFileInputMaxSize?: number
606638
toolCalling?: boolean
639+
experimentalToolCallReply?: boolean
607640
isForceMute?: boolean
608641
coolDownTime?: number
609642
muteTime?: number
@@ -628,45 +661,46 @@ type LegacyConfig = Config & {
628661

629662
type CommonMigration = {
630663
key:
631-
| 'maxMessages'
632-
| 'maxTokens'
633-
| 'image'
634-
| 'imageInputMaxCount'
635-
| 'imageInputMaxSize'
636-
| 'multimodalFileInputMaxSize'
637-
| 'toolCalling'
638-
| 'isForceMute'
639-
| 'coolDownTime'
640-
| 'splitVoice'
641-
| 'isNickname'
642-
| 'isNickNameWithContent'
643-
| 'statusPersistence'
644-
| 'historyPull'
645-
| 'modelCompletionCount'
646-
| 'enableMessageId'
664+
| 'maxMessages'
665+
| 'maxTokens'
666+
| 'image'
667+
| 'imageInputMaxCount'
668+
| 'imageInputMaxSize'
669+
| 'multimodalFileInputMaxSize'
670+
| 'toolCalling'
671+
| 'experimentalToolCallReply'
672+
| 'isForceMute'
673+
| 'coolDownTime'
674+
| 'splitVoice'
675+
| 'isNickname'
676+
| 'isNickNameWithContent'
677+
| 'statusPersistence'
678+
| 'historyPull'
679+
| 'modelCompletionCount'
680+
| 'enableMessageId'
647681
privateDefault: number | boolean
648682
groupDefault: number | boolean
649683
onlyFalse?: boolean
650684
}
651685

652686
type IdleMigration = {
653687
key:
654-
| 'enableLongWaitTrigger'
655-
| 'idleTriggerIntervalMinutes'
656-
| 'idleTriggerRetryStyle'
657-
| 'idleTriggerMaxIntervalMinutes'
658-
| 'idleTriggerFixedMaxRetries'
659-
| 'enableIdleTriggerJitter'
688+
| 'enableLongWaitTrigger'
689+
| 'idleTriggerIntervalMinutes'
690+
| 'idleTriggerRetryStyle'
691+
| 'idleTriggerMaxIntervalMinutes'
692+
| 'idleTriggerFixedMaxRetries'
693+
| 'enableIdleTriggerJitter'
660694
privateDefault: number | boolean | 'exponential' | 'fixed'
661695
groupDefault: number | boolean | 'exponential' | 'fixed'
662696
onlyFalse?: boolean
663697
}
664698

665699
type GroupMigration = {
666700
key:
667-
| 'messageActivityScoreLowerLimit'
668-
| 'messageActivityScoreUpperLimit'
669-
| 'isAt'
701+
| 'messageActivityScoreLowerLimit'
702+
| 'messageActivityScoreUpperLimit'
703+
| 'isAt'
670704
defaultValue: number | boolean
671705
}
672706

@@ -690,6 +724,11 @@ const commonMigrations: CommonMigration[] = [
690724
groupDefault: true,
691725
onlyFalse: true
692726
},
727+
{
728+
key: 'experimentalToolCallReply',
729+
privateDefault: false,
730+
groupDefault: false
731+
},
693732
{
694733
key: 'isForceMute',
695734
privateDefault: true,
@@ -764,6 +803,7 @@ const legacyKeys = [
764803
'imageInputMaxSize',
765804
'multimodalFileInputMaxSize',
766805
'toolCalling',
806+
'experimentalToolCallReply',
767807
'isForceMute',
768808
'coolDownTime',
769809
'muteTime',
@@ -804,7 +844,6 @@ export function migrateConfig(config: Config): boolean {
804844
IdleMigration['key'],
805845
IdleValue
806846
>
807-
808847
if (
809848
config.globalPrivateConfig.preset === 'CHARACTER' &&
810849
config.defaultPreset

src/index.ts

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ import { MessageCollector } from './service/message'
66
import { TriggerStore } from './service/trigger'
77
import { dirname, resolve } from 'path'
88
import { fileURLToPath } from 'url'
9-
import type {} from '@koishijs/plugin-console'
9+
import type { } from '@koishijs/plugin-console'
1010

1111
export function apply(ctx: Context, config: Config) {
1212
const changed = migrateConfig(config)
@@ -127,6 +127,12 @@ export const usage = `
127127
128128
请先阅读[**此文档**](https://chatluna.chat/ecosystem/other/character.html)了解使用方式。
129129
130+
### 26.04.11
131+
132+
“工具调用回复”功能的配置项已从“基础配置”下放至全局私聊/全局群聊/分私聊/分群聊配置中,并且支持分别调整 \`status\`、\`think\`、\`next_reply\`、\`wake_up_reply\` 字段是否启用。
133+
134+
使用“工具调用回复”功能时,请尽可能使用模型官方(推荐的)API 格式(如:Gemini 使用 Gemini 适配器,Claude 及其他支持 Anthropic API 的模型使用 Claude 适配器),否则可能遇到无法正常完成回复的问题(尤其是 Minimax 等模型)。
135+
130136
### 26.04.05
131137
132138
伪装插件新增实验性“工具调用回复”功能,详情请查看文档。

0 commit comments

Comments
 (0)