fix(channel): expose execution trace switch for WeChat channels (#613)

This commit is contained in:
matevip 2026-08-21 22:24:37 -04:00
parent 14df331ce6
commit 709218e2ac
4 changed files with 33 additions and 6 deletions

View File

@ -472,6 +472,7 @@ import {
extractChannelFields,
extractRenderConfig,
parseConfigJson,
supportsChannelMessageFilter,
type AccessControlValue,
type RenderConfigValue,
} from '@/utils/channelConfigJson'
@ -633,13 +634,8 @@ const needsWebhookUrl = computed(() => {
return true
})
// Browser-rendered channels stream structured message parts over SSE and let
// the client decide what to draw (thinking panel, tool cards). They never go
// through the adapter's outbound text render path, which is the only place the
// message-filter config is read so the controls would be inert there.
const BROWSER_RENDERED_TYPES = ['web', 'webchat']
const supportsMessageFilter = computed(
() => !BROWSER_RENDERED_TYPES.includes(form.value.channelType || ''),
() => supportsChannelMessageFilter(form.value.channelType),
)
const isLocalhost = computed(() => {

View File

@ -673,6 +673,7 @@ export const CHANNEL_FIELD_DEFS: Record<string, ChannelFieldDef[]> = {
{ key: 'bot_id', label: '机器人 ID', placeholder: 'bot_xxxxxxxxxx', required: true, type: 'text', tooltip: '企业微信智能机器人的 Bot ID在企业微信后台创建智能机器人后获取' },
{ key: 'secret', label: 'Secret', placeholder: 'xxxxxxxxxxxxxxxx', required: true, sensitive: true, type: 'password', tooltip: '企业微信智能机器人的 Secret' },
{ key: 'welcome_text', label: '欢迎消息', placeholder: '你好!我是你的 AI 助手', type: 'text', tooltip: '用户首次进入对话时自动发送的欢迎消息(留空则不发送)' },
{ key: 'stream_progress', label: '执行轨迹', placeholder: '', type: 'switch', defaultValue: true, tooltip: '展示处理期间的实时进度与阶段旁白;关闭后仅发送最终答复。原始思考和工具名称仍受下方过滤开关控制' },
{ key: 'media_download_enabled', label: '媒体下载', placeholder: '', type: 'switch', defaultValue: false, tooltip: '下载消息中的图片和文件到本地并解密(需要本地磁盘空间)' },
{ key: 'media_dir', label: '媒体目录', placeholder: 'data/media', type: 'text', tooltip: '媒体文件保存目录(默认 data/media' },
{ key: 'max_reconnect_attempts', label: '最大重连次数', placeholder: '-1 表示无限重连', type: 'number', defaultValue: -1, tooltip: 'WebSocket 断线后最大重连次数,-1 为无限重连' },
@ -680,6 +681,7 @@ export const CHANNEL_FIELD_DEFS: Record<string, ChannelFieldDef[]> = {
weixin: [
{ key: 'bot_token', label: 'Bot Token', placeholder: '扫码登录后自动获取', required: true, sensitive: true, type: 'password', tooltip: '微信 iLink Bot Token通过扫描二维码登录获取' },
{ key: 'base_url', label: 'API 地址', placeholder: 'https://ilinkai.weixin.qq.com', type: 'text', defaultValue: 'https://ilinkai.weixin.qq.com', tooltip: 'iLink Bot API 基础地址(通常无需修改)' },
{ key: 'stream_progress', label: '执行轨迹', placeholder: '', type: 'switch', defaultValue: true, tooltip: '展示处理期间的实时进度与阶段旁白;关闭后仅发送最终答复。原始思考和工具名称仍受下方过滤开关控制' },
{ key: 'media_download_enabled', label: '媒体下载', placeholder: '', type: 'switch', defaultValue: false, tooltip: '下载消息中的图片、文件、视频到本地并解密' },
{ key: 'media_dir', label: '媒体目录', placeholder: 'data/media', type: 'text', tooltip: '媒体文件保存目录(默认 data/media' },
],

View File

@ -0,0 +1,20 @@
import { describe, expect, it } from 'vitest'
import { supportsChannelMessageFilter } from '../channelConfigJson'
import { CHANNEL_FIELD_DEFS } from '../../types'
describe('supportsChannelMessageFilter', () => {
it('exposes message filter controls for WeCom and Weixin channels', () => {
expect(supportsChannelMessageFilter('wecom')).toBe(true)
expect(supportsChannelMessageFilter('weixin')).toBe(true)
})
it('hides message filter controls for browser-rendered channels', () => {
expect(supportsChannelMessageFilter('web')).toBe(false)
expect(supportsChannelMessageFilter('webchat')).toBe(false)
})
it('exposes execution trace controls for WeCom and Weixin channels', () => {
expect(CHANNEL_FIELD_DEFS.wecom.map(field => field.key)).toContain('stream_progress')
expect(CHANNEL_FIELD_DEFS.weixin.map(field => field.key)).toContain('stream_progress')
})
})

View File

@ -29,6 +29,15 @@ export const defaultRenderConfig = (): RenderConfigValue => ({
message_format: 'auto',
})
// Browser-rendered channels stream structured message parts over SSE and let
// the client decide what to draw. They never go through the adapter's outbound
// text render path, where message-filter config is read.
const BROWSER_RENDERED_TYPES = new Set(['web', 'webchat'])
export function supportsChannelMessageFilter(channelType?: string | null): boolean {
return !BROWSER_RENDERED_TYPES.has(channelType || '')
}
export function parseConfigJson(json?: string): Record<string, any> {
if (!json) return {}
try { return JSON.parse(json) } catch { return {} }