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
2 changes: 1 addition & 1 deletion packages/adapter-azure-openai/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@
"adapter"
],
"dependencies": {
"@chatluna/v1-shared-adapter": "^1.0.36",
"@chatluna/v1-shared-adapter": "^1.0.37",
"@langchain/core": "^0.3.80",
"zod": "3.25.76",
"zod-to-json-schema": "^3.24.6"
Expand Down
2 changes: 1 addition & 1 deletion packages/adapter-claude/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@
"adapter"
],
"dependencies": {
"@chatluna/v1-shared-adapter": "^1.0.36",
"@chatluna/v1-shared-adapter": "^1.0.37",
"@langchain/core": "^0.3.80",
"zod": "3.25.76",
"zod-to-json-schema": "^3.24.6"
Expand Down
2 changes: 1 addition & 1 deletion packages/adapter-deepseek/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@
"adapter"
],
"dependencies": {
"@chatluna/v1-shared-adapter": "^1.0.36",
"@chatluna/v1-shared-adapter": "^1.0.37",
"@langchain/core": "^0.3.80",
"zod": "3.25.76",
"zod-to-json-schema": "^3.24.6"
Expand Down
2 changes: 1 addition & 1 deletion packages/adapter-doubao/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@
"adapter"
],
"dependencies": {
"@chatluna/v1-shared-adapter": "^1.0.36",
"@chatluna/v1-shared-adapter": "^1.0.37",
"@langchain/core": "^0.3.80",
"zod": "3.25.76",
"zod-to-json-schema": "^3.24.6"
Expand Down
2 changes: 1 addition & 1 deletion packages/adapter-gemini/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@
],
"dependencies": {
"@anatine/zod-openapi": "^2.2.8",
"@chatluna/v1-shared-adapter": "^1.0.36",
"@chatluna/v1-shared-adapter": "^1.0.37",
"@langchain/core": "^0.3.80",
"openapi3-ts": "^4.5.0",
"zod": "3.25.76",
Expand Down
2 changes: 1 addition & 1 deletion packages/adapter-hunyuan/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@
"adapter"
],
"dependencies": {
"@chatluna/v1-shared-adapter": "^1.0.36",
"@chatluna/v1-shared-adapter": "^1.0.37",
"@langchain/core": "^0.3.80",
"zod": "3.25.76",
"zod-to-json-schema": "^3.24.6"
Expand Down
2 changes: 1 addition & 1 deletion packages/adapter-ollama/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@
"adapter"
],
"dependencies": {
"@chatluna/v1-shared-adapter": "^1.0.36",
"@chatluna/v1-shared-adapter": "^1.0.37",
"@langchain/core": "^0.3.80"
},
"devDependencies": {
Expand Down
4 changes: 2 additions & 2 deletions packages/adapter-openai-like/package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "koishi-plugin-chatluna-openai-like-adapter",
"description": "openai style api adapter for chatluna",
"version": "1.4.0-alpha.4",
"version": "1.4.0-alpha.5",
"main": "lib/index.cjs",
"module": "lib/index.mjs",
"typings": "lib/index.d.ts",
Expand Down Expand Up @@ -60,7 +60,7 @@
"adapter"
],
"dependencies": {
"@chatluna/v1-shared-adapter": "^1.0.36",
"@chatluna/v1-shared-adapter": "^1.0.37",
"@langchain/core": "^0.3.80",
"zod": "3.25.76",
"zod-to-json-schema": "^3.24.6"
Expand Down
4 changes: 2 additions & 2 deletions packages/adapter-openai/package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "koishi-plugin-chatluna-openai-adapter",
"description": "openai adapter for chatluna",
"version": "1.4.0-alpha.4",
"version": "1.4.0-alpha.5",
"main": "lib/index.cjs",
"module": "lib/index.mjs",
"typings": "lib/index.d.ts",
Expand Down Expand Up @@ -60,7 +60,7 @@
"adapter"
],
"dependencies": {
"@chatluna/v1-shared-adapter": "^1.0.36",
"@chatluna/v1-shared-adapter": "^1.0.37",
"@langchain/core": "^0.3.80",
"zod": "3.25.76",
"zod-to-json-schema": "^3.24.6"
Expand Down
4 changes: 2 additions & 2 deletions packages/adapter-qwen/package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "koishi-plugin-chatluna-qwen-adapter",
"description": "qwen adapter for chatluna",
"version": "1.4.0-alpha.1",
"version": "1.4.0-alpha.2",
"main": "lib/index.cjs",
"module": "lib/index.mjs",
"typings": "lib/index.d.ts",
Expand Down Expand Up @@ -60,7 +60,7 @@
"adapter"
],
"dependencies": {
"@chatluna/v1-shared-adapter": "^1.0.36",
"@chatluna/v1-shared-adapter": "^1.0.37",
"@langchain/core": "^0.3.80",
"zod": "3.25.76",
"zod-to-json-schema": "^3.24.6"
Expand Down
2 changes: 1 addition & 1 deletion packages/adapter-rwkv/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@
"adapter"
],
"dependencies": {
"@chatluna/v1-shared-adapter": "1.0.36",
"@chatluna/v1-shared-adapter": "1.0.37",
"@langchain/core": "^0.3.80",
"zod-to-json-schema": "3.23.5"
},
Expand Down
2 changes: 1 addition & 1 deletion packages/adapter-spark/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@
"adapter"
],
"dependencies": {
"@chatluna/v1-shared-adapter": "^1.0.36",
"@chatluna/v1-shared-adapter": "^1.0.37",
"@langchain/core": "^0.3.80",
"zod": "3.25.76",
"zod-to-json-schema": "^3.24.6"
Expand Down
2 changes: 1 addition & 1 deletion packages/adapter-wenxin/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@
"adapter"
],
"dependencies": {
"@chatluna/v1-shared-adapter": "^1.0.36",
"@chatluna/v1-shared-adapter": "^1.0.37",
"@langchain/core": "^0.3.80",
"zod": "3.25.76",
"zod-to-json-schema": "^3.24.6"
Expand Down
2 changes: 1 addition & 1 deletion packages/adapter-zhipu/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@
"adapter"
],
"dependencies": {
"@chatluna/v1-shared-adapter": "^1.0.36",
"@chatluna/v1-shared-adapter": "^1.0.37",
"@langchain/core": "^0.3.80",
"jsonwebtoken": "^9.0.2",
"zod": "3.25.76",
Expand Down
1 change: 1 addition & 0 deletions packages/core/src/locales/en-US.yml
Original file line number Diff line number Diff line change
Expand Up @@ -568,6 +568,7 @@ chatluna:
fixed_model: 'The current route fixes the model to {0}.'
fixed_preset: 'The current route fixes the preset to {0}.'
fixed_chat_mode: 'The current route fixes the chat mode to {0}.'
invalid_chat_mode: 'Chat mode {0} is unavailable. Check the input and try again.'
switch_success: 'Switched to: {0}'
switch_failed: 'Failed to switch conversation: {0}'
list_header: 'Conversations in the current route:'
Expand Down
1 change: 1 addition & 0 deletions packages/core/src/locales/zh-CN.yml
Original file line number Diff line number Diff line change
Expand Up @@ -567,6 +567,7 @@ chatluna:
fixed_model: '当前路由已将模型固定为 {0}。'
fixed_preset: '当前路由已将预设固定为 {0}。'
fixed_chat_mode: '当前路由已将聊天模式固定为 {0}。'
invalid_chat_mode: '聊天模式 {0} 不可用,请检查输入是否正确。'
switch_success: '已切换到:{0}'
switch_failed: '切换会话失败:{0}'
list_header: '当前路由下的会话列表:'
Expand Down
8 changes: 8 additions & 0 deletions packages/core/src/middlewares/system/conversation_manage.ts
Original file line number Diff line number Diff line change
Expand Up @@ -979,6 +979,14 @@ function formatConversationError(
])
}

const invalidMode = error.message.match(/^Chat mode (.+) not found\.$/)
if (invalidMode) {
return session.text(
'chatluna.conversation.messages.invalid_chat_mode',
[invalidMode[1]]
)
}

if (action != null) {
return session.text('chatluna.conversation.messages.action_failed', [
session.text(`chatluna.conversation.action.${action}`),
Expand Down
18 changes: 18 additions & 0 deletions packages/core/src/services/conversation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -605,6 +605,8 @@ export class ConversationService {
setActive?: boolean
}
) {
this.checkChatMode(options.chatMode)

return runLock(this._bindingLocks, options.bindingKey, async () => {
const now = new Date()
const conversation: ConversationRecord = {
Expand Down Expand Up @@ -1561,6 +1563,8 @@ export class ConversationService {
throw new Error('Conversation update is locked by constraint.')
}

this.checkChatMode(options.chatMode)

const updated = await this.touchConversation(conversation.id, {
model: options.model,
preset: options.preset,
Expand Down Expand Up @@ -1690,6 +1694,9 @@ export class ConversationService {
session: Session,
patch: Partial<ConstraintRecord>
) {
this.checkChatMode(patch.defaultChatMode)
this.checkChatMode(patch.fixedChatMode)

const current = await this.getManagedConstraint(session)
const now = new Date()
const route = session.isDirect
Expand Down Expand Up @@ -1746,6 +1753,17 @@ export class ConversationService {
return this.config.defaultGroupRouteMode ?? 'shared'
}

private checkChatMode(mode?: string | null) {
if (
mode != null &&
!this.ctx.chatluna.platform.chatChains.value.some(
(chain) => chain.name === mode
)
) {
throw new Error(`Chat mode ${mode} not found.`)
}
}

private async allocateConversationSeq(bindingKey: string) {
const [latest] = (await this.ctx.database.get(
'chatluna_conversation',
Expand Down
2 changes: 1 addition & 1 deletion packages/extension-agent/package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "koishi-plugin-chatluna-agent",
"description": "Agent framework for ChatLuna",
"version": "1.0.26",
"version": "1.0.27",
"main": "lib/index.cjs",
"module": "lib/index.mjs",
"typings": "lib/index.d.ts",
Expand Down
11 changes: 10 additions & 1 deletion packages/extension-agent/src/service/trigger.ts
Original file line number Diff line number Diff line change
Expand Up @@ -571,6 +571,7 @@ export class ChatLunaAgentTriggerService {
...task.wakeupTemplate,
...override,
target,
bindingKey: override?.bindingKey ?? task.bindingKey,
requestId,
conversationId: override?.conversationId ?? task.conversationId,
presetLane: override?.presetLane ?? task.presetLane,
Expand Down Expand Up @@ -924,11 +925,19 @@ export class ChatLunaAgentTriggerService {
}
const next = await provider.prepare?.({ input: merged, task })

return {
const result: Partial<TriggerTask> = {
...patch,
...next,
params: { ...(patch.params ?? {}), ...(next?.params ?? {}) }
}

if (patch.bindingKey != null && patch.bindingKey !== task.bindingKey) {
result.conversationId = null
} else if (patch.conversationId !== undefined) {
result.conversationId = patch.conversationId
}
Comment thread
dingyi222666 marked this conversation as resolved.

return result
}
}

Expand Down
80 changes: 58 additions & 22 deletions packages/extension-agent/src/skills/builtin.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
/** @module skills/builtin */

import { cp, mkdir, readdir, readFile, rm, stat, writeFile } from 'fs/promises'
import { join } from 'path'
import { copyFile, mkdir, readdir, readFile, rm, stat } from 'fs/promises'
import { dirname, join, relative } from 'path'
import { Context } from 'koishi'
import { AGENTCLI_SKILL_NAME } from '../computer/materialize'
import { getSkillsRootPath } from '../config/path'
Expand Down Expand Up @@ -41,29 +41,65 @@ export async function syncBundledSkills(ctx: Context) {
continue
}

let preservedConfig: Buffer | undefined
let backupPath: string | undefined
if (force && current?.isFile()) {
const configPath = join(to, 'config.json')
preservedConfig = await readFile(configPath).catch(() => undefined)
if (preservedConfig) {
backupPath = join(dest, `${entry.name}.config.json.bak`)
await writeFile(backupPath, preservedConfig).catch(() => {})
}
}

await rm(to, { recursive: true, force: true })
await cp(from, to, { recursive: true })
const synced = await syncSkillDir(from, to, force && current?.isFile())

if (preservedConfig) {
await writeFile(join(to, 'config.json'), preservedConfig)
if (backupPath) {
await rm(backupPath, { force: true })
}
}
if (!synced && force && current?.isFile()) continue

ctx.logger[force && current?.isFile() ? 'debug' : 'info'](
`${force && current?.isFile() ? 'Refreshed' : 'Copied'} bundled skill '${entry.name}' to ${to}${preservedConfig ? ' (preserved config.json)' : ''}`
`${force && current?.isFile() ? 'Refreshed' : 'Copied'} bundled skill '${entry.name}' to ${to}`
)
}
}

async function syncSkillDir(from: string, to: string, preserveConfig: boolean) {
const files = await collectFiles(from)
const current = await collectFiles(to).catch(() => [])
const source = new Set(files)
let changed = false

for (const file of files) {
if (preserveConfig && file === 'config.json') continue

const src = join(from, file)
const dest = join(to, file)
const data = await readFile(src)
const old = await readFile(dest).catch(() => undefined)
if (old?.equals(data)) continue

await mkdir(dirname(dest), { recursive: true })
await copyFile(src, dest)
changed = true
}

for (const file of current) {
if (source.has(file)) continue
if (preserveConfig && file === 'config.json') continue

await rm(join(to, file), { force: true })
changed = true
}

return changed
}

async function collectFiles(dir: string) {
const files: string[] = []
const dirs = [dir]

while (dirs.length) {
const current = dirs.shift()!
const entries = await readdir(current, { withFileTypes: true })

for (const entry of entries) {
const path = join(current, entry.name)
if (entry.isDirectory()) {
dirs.push(path)
continue
}

if (entry.isFile()) files.push(relative(dir, path))
}
}

return files.sort((a, b) => a.localeCompare(b))
}
13 changes: 13 additions & 0 deletions packages/extension-agent/src/skills/watch.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,16 +24,29 @@ export async function watchSkillFiles(
const watchers: FSWatcher[] = []
let timer: NodeJS.Timeout | undefined
let closed = false
let reloading = false
let pending = false

const schedule = () => {
if (closed) return
if (reloading) {
pending = true
return
}
clearTimeout(timer)
timer = setTimeout(async () => {
timer = undefined
reloading = true
try {
await reload()
} catch (err) {
ctx.logger.error('Failed to hot reload skills', err)
} finally {
reloading = false
if (pending) {
pending = false
schedule()
}
}
}, 100)
}
Expand Down
Loading