qwen-code Web Shell 渠道会话作用域(sessionScope)管理指南:从配置到端到端验证

发布时间:2026/9/12 12:58:42
qwen-code Web Shell 渠道会话作用域(sessionScope)管理指南:从配置到端到端验证
qwen-code Web Shell 渠道会话作用域sessionScope管理指南从配置到端到端验证【免费下载链接】qwen-codeAn open-source AI coding agent that lives in your terminal.项目地址: https://gitcode.com/GitHub_Trending/qw/qwen-code导读qwen-code 的渠道运行时channel runtime早已根据sessionScope路由入站消息但此前 Web Shell 的渠道编辑器中只能看到平台相关的凭据与访问策略字段用户无法选择哪些会话conversation共享同一个 Agent 会话。本文基于 docs/design/2026-08-03-web-shell-channel-session-scope.md 设计方案完整讲解sessionScope的四种取值语义、渠道目录catalog如何为每个可管理渠道类型暴露该字段、Web Shell 编辑器如何在专属 Session 区域渲染并持久化该配置以及新旧配置的兼容性与验证路径帮助你在部署渠道接入时精确控制 Agent 会话的共享边界。背景为什么需要渠道会话作用域qwen-code 作为运行在终端中的开源 AI 编程 Agent通过渠道channel机制接入 DingTalk、GitHub、GitLab、DWS、飞书、企微等平台。每条入站消息到达渠道运行时后会被路由到某个 Agent 会话session执行。问题在于运行时早已按sessionScope路由消息该字段决定哪些会话共享同一个 Agent 会话但 Web Shell 的渠道编辑器此前只渲染平台特有的管理字段凭据、访问策略等用户无法看到或修改会话作用域结果就是用户可以配置谁能访问却不能配置这些会话之间是否共享同一个 Agent 会话。这个设计文档的目的就是把运行时的sessionScope能力透出到管理面让用户在 Web Shell 渠道编辑器中为每个可管理的渠道类型显式选择会话作用域。会话作用域的四种取值语义设计文档定义了四种作用域对应SessionScope联合类型。从 types.ts 可以看到运行时的类型定义export type SessionScope user | thread | chat_thread | single;四种取值在渠道目录中分别对应如下语义与 Web Shell 编辑器中的选项标签一致见 channel-registry.ts取值语义编辑器选项标签user每个发送者sender与每个聊天chat各一个会话Per User and Chatthread每个路由线程thread一个会话回退到聊天级别Per Thread (Legacy)chat_thread每个聊天与嵌套线程各一个会话Per Chat and Threadsingle整个渠道实例共享同一个会话One Shared Session实践要点user是粒度最细的选项同一用户在 A 群与 B 群的对话互不干扰适合权限隔离要求高的场景chat_thread在聊天维度之上叠加线程维度适合带主题/话题topic结构的平台如飞书话题、钉钉内部话题single让整个渠道实例共享一份会话历史适合内部单聊入口等需要上下文延续的场景thread是遗留取值类型注释明确说明仅为既有配置保留retained for existing configurations only新配置通常不应再选择它。渠道目录将共享字段注入每个可管理渠道设计的核心实现位于 daemon 的渠道注册表registry。supportedChannelCatalog()从注册表导出每个渠道的描述符见 channel-registry.ts其中manageable: management ! undefined标记渠道是否可管理fields通过managementFieldsWithSharedControls()生成function managementFieldsWithSharedControls( fields: readonly ChannelConfigFieldDescriptor[], defaultSessionScope: SessionScope, ): readonly ChannelConfigFieldDescriptor[] { const declared new Set(fields.map((field) field.key)); const normalizedFields fields.map((field) field.key sessionScope field.default undefined ? { ...field, default: defaultSessionScope } : field, ); return [ ...normalizedFields, ...SHARED_ACCESS_FIELDS.filter((field) !declared.has(field.key)), ...(declared.has(sessionScope) ? [] : [ /* 注入 sessionScope 枚举字段 */ { key: sessionScope, label: Session Scope, kind: enum, required: true, default: defaultSessionScope, description: Controls how conversations share persistent agent sessions, options: SESSION_SCOPE_OPTIONS, }, ]), /* multiSession / instructions 等共享字段依此类推 */ ]; }这段代码体现了三个关键设计决策优先保留插件自有字段如果某个渠道插件自己声明了sessionScope字段declared.has(sessionScope)目录直接沿用不重复注入未声明则注入标准枚举否则注入kind: enum的sessionScope字段options为SESSION_SCOPE_OPTIONS即上表四种取值required: true默认值来自插件defaultSessionScope取自plugin.defaultSessionScope ?? user——插件未声明时统一回退到user。在插件一侧ChannelPlugin接口提供了可选的defaultSessionScope声明见 types.tsexport interface ChannelPlugin { channelType: string; displayName: string; // ... /** Default Channel routing scope (applied when config omits sessionScope). */ defaultSessionScope?: SessionScope; createChannel(name, config, bridge, options?): ChannelBase; }从源码可以确认的实际默认值GitHub 与 GitLab 渠道插件声明defaultSessionScope: chat_thread见 github/src/index.ts、gitlab/src/index.tsDWS 渠道同样声明chat_thread见 dws/src/index.ts而 DingTalk 未声明defaultSessionScope因此注册表回退到user见 DingtalkAdapter.ts 相关注释。注册表在构建时还会校验字段合法性sessionScope必须是枚举类型且其选项必须包含渠道声明的defaultSessionScope否则直接抛错拒绝注册见 channel-registry.ts。Web Shell 编辑器专属 Session 区渲染与默认值回填在 Web Shell 端渠道编辑器把描述符字段按类别拆分展示。ChannelEditorDialog定义了共享会话字段键集合见 ChannelEditorDialog.tsxsessionScope,编辑器将字段划分为 access访问策略、session会话、credential凭据三组sessionScope落入会话组并单独提取为高优先级字段const sessionFields descriptor.fields.filter((field) SHARED_SESSION_FIELD_KEYS.has(field.key), ); const sessionScopeField sessionFields.find( (field) field.key sessionScope field.kind enum, );渲染时ChannelEditorDialog.tsx 区域编辑器在专属的 Session 区样式见 ChannelEditorDialog.module.css内渲染作用域选项每个选项有独立的 radio 控件与描述文案支持data-selected选中态样式。值得注意的兼容性处理编辑器对thread选项做了条件过滤ChannelEditorDialog.tsxconst sessionScopeOptions (sessionScopeField?.options ?? []).filter( (option) option.value ! thread || instance?.config.sessionScope thread || (instance ! undefined instance.config.sessionScope undefined sessionScopeField?.default thread), );即新配置默认不展示thread选项只有当前实例已显式配置为thread、或实例未配置但字段默认值就是thread时才显示避免用户新建渠道时误选遗留取值。编辑器对新建new与既有legacy草稿统一通过createChannelEditorDraft(descriptor, instance)初始化未保存的草稿会显示字段声明的有效默认值保存时通过既有的渠道 upsert 请求把选中值写回 daemon。配置持久化与合法性校验保存环节由 daemon 侧的渠道设置存储channel settings store负责。assertSharedField对共享字段做枚举白名单校验见 channel-settings-store.tsconst enumValues: Recordstring, ReadonlySetstring { senderPolicy: new Set([allowlist, pairing, open]), dmPolicy: new Set([open, disabled]), groupPolicy: new Set([disabled, allowlist, pairing, open]), sessionScope: new Set([user, thread, chat_thread, single]), dispatchMode: new Set([steer, followup, collect]), }; if (Object.hasOwn(enumValues, key)) { if (typeof value ! string || !enumValues[key]!.has(value)) { throw invalidConfig(Channel field ${key} has an invalid value.); } }也就是说管理存储只接受user / thread / chat_thread / single四个运行时支持的取值其余值一律按非法配置拒绝。这也印证了设计文档中管理存储接受每个运行时支持的 scope这一验证点。在 upsert 时sessionScope还会参与multiSession兼容性检查——当配置未显式携带sessionScope时用plugin.defaultSessionScope ?? user兜底参与校验见 channel-settings-store.ts确保跨字段约束命名会话、群历史上限等在正确的会话语义下判定。兼容性设计设计文档明确要求保持运行时与持久化格式不变具体体现为运行时路由不变ChannelBase的入站处理继续按既有sessionScope语义路由本次改动不触碰路由逻辑配置格式不变已存在、未携带sessionScope的配置继续沿用插件默认作用域直到用户编辑并保存后才落盘显式值。这保证了存量渠道平滑升级不会因目录新增字段而改变行为不可管理渠道不暴露字段supportedChannelCatalog()中manageable: management ! undefined没有management描述符的渠道类型在 Web Shell 中不展示sessionScope其行为完全由插件内部决定。端到端验证路径设计文档列出了四个验证点结合仓库测试可以逐条对应断言 DingTalk 与 GitHub 的目录默认值GitHub 声明chat_thread其单测declares chat_thread as defaultSessionScope直接断言插件默认值见 GithubAdapter.test.tsDingTalk 未声明则回退user其适配器测试覆盖了回退路径见 DingtalkAdapter.test.ts。断言管理存储接受全部运行时 scopeassertSharedField的枚举白名单即该约束的实现管理存储的 upsert 测试channel-settings-store.test.ts对四种取值均有覆盖。断言新建与遗留草稿使用有效默认值Web Shell 编辑器测试覆盖了实例未配置 sessionScope 时字段默认值回填与legacy 配置显式 thread 时选项保留的场景见 ChannelEditorDialog.test.tsx。端到端选择并持久化非默认 scope编辑器中选中非默认值如single并保存配置经渠道 upsert 请求写入 daemon 设置存储随后由运行时按新语义路由——这一闭环可通过 Web Shell 管理界面手动验证也可由组件测试ChannelEditorDialog.test.tsx 等用例驱动。小结sessionScope从运行时内部路由参数升级为Web Shell 可管理配置项补齐了渠道管理面的最后一块拼图用户在配置凭据与访问策略的同时可以显式决定会话共享粒度。本文梳理的实现链路为渠道插件声明defaultSessionScope→ 注册表目录为每个可管理渠道注入/校验sessionScope枚举 → Web Shell 编辑器在 Session 区渲染并提供默认值 → 保存时经渠道 upsert 写入 daemon 存储 → 白名单校验后交给运行时路由。理解这条链路后你既可以正确规划渠道的会话边界也能在排查为什么两个群共享了同一份上下文这类问题时快速定位到sessionScope这一关键开关。【免费下载链接】qwen-codeAn open-source AI coding agent that lives in your terminal.项目地址: https://gitcode.com/GitHub_Trending/qw/qwen-code创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考