跳到正文
FunCoding

搜索

搜索文档、Skill 和 MCP

渠道显示与投递契约

保留命名任务来源标签,分离原始响应和平台展示,并验证主动发送目标。

一个 agent 响应可能被拆成多条消息、流式卡片、最终回复或重启后的重试。每个独立可见边界都需要正确归属,不能只在第一个 chunk 加一次标签。

命令和活动指示

适配器可用 registerCommand 注册自定义命令,handler 返回 true 表示已处理、不再转给 agent。onPromptStart()/onPromptEnd() 可显示输入状态;它们只在 prompt 真正开始处理时触发,不对 collect 缓冲中或被门禁拒绝的消息展示正在执行。

onToolCall() 可呈现工具活动。onResponseChunk(chatId, chunk, sessionId, segment) 用于增量显示,onResponseComplete(...) 处理最终结果,onOutputSegmentEnd() 清理适配器自己持有的分段状态。

sourceLabel

daemon 命名任务模式的 segment.sourceLabel 是该段不可变的投递元数据。每条独立显示的消息/卡片都展示一次,包括单独显示的最终回复;不要将标签写进原始 buffer 或模型文本。

sendThreadMessage(chatId, threadId, text, sourceLabel) 同样接收可选纯文本标签,覆盖一次性及主动投递。覆盖发送、分块、卡片或 fallback 的适配器必须在各边界保留标签,只按目标 markup 转义标签本身,并把其显示长度算入平台容量。

no-reply 检查、媒体标记解析、审计 hash、transcript 持久化和重试 body 捕获都针对原始响应先进行。若为重启重试保存投递,应把捕获的 label 单独保存,而不是把已装饰文本当原始回复再次处理。

交互式 ChannelUserInputRequestContext 也含 sourceLabel。卡片、终端替代和纯文本 fallback 都保留它,但不能为此放宽 request、session、run、owner 或 target 的原有校验。

主动发送

默认不声明主动发送能力。平台确实可在没有活跃入站请求时投递,才将 supportsProactiveSend() 设为 true;基类会用此能力处理持久 loops、Webhook、后台结果和 daemon delivery。

默认主动目标策略拒绝带 threadId 的目标。只有平台确实能投递相应 thread,才覆盖 supportsProactiveTarget;通用 daemon 投递与 Webhook 若支持不同目标形状,分别使用 supportsProactiveDeliveryTarget、supportsProactiveWebhookTarget。

pushProactive(target, text, sourceLabel) 应继续传递标签并使用正确 chat/thread。无法投递的目标保持拒绝,不退回另一群、私聊或主线程,避免把结果交给错误收件人。

两种宿主

独立 qwen channel start 使用 ACP-backed 服务;daemon 模式的 worker 单独运行,经 SDK 回连 owning workspace。命名渠道必须恰好属于一个可信注册工作区,worker 使用其规范 cwd 和环境覆盖。

平台 SDK 失败被隔离在 worker 中,但插件仍需要自己的连接释放、平台限额和投递错误处理。不能因为 ChannelBase 已处理通用重启,就承诺平台发送恰好一次或每个适配器支持全部后台目标。