Commit Graph

6 Commits

Author SHA1 Message Date
1d4f2beeea fix(prompt): 去掉"每轮只能发一次 output_send"的凭空限制;type 缺省即 text
用户现场指出:**qq 插件的输出通道判据太严了**(那条判据在插件侧,已单独修:
`output_send__qq` 不再受"当前会话身份"限制)。同时内核提示词里还有一条**同类的凭空限制**:

  「每轮对话**通常只需调用一次** output_send__{通道名} 即可完成回复。
    仅在内容确实超过单条消息长度上限(如 >4000 字)时才拆分为多条」

可设计上输出是 agent 的**主动调用**:收到一次输入后,可以往**任意(已授权的)通道**
发**任意多次**(分段播报、先回执后结论、同时通知多个通道都合法)。这句话会让模型
自己收起合理的多次输出 —— 而且它不是任何机制的要求,只是当初为压 output-loop 写的
措辞(真正的防环机制是"回执只回 ok、不回传富结果",那条保留)。

改法:
- 提示词改为明确授权:**输出次数与目标通道由你自己决定**,没有「一轮只能发一次」的限制;
  只保留两条真话:单条长度上限(超长拆完整段落)、别反复重发**完全相同**的内容。
- `output_send__*` 的 `type` 参数改为**可选**(缺省 text):判据该拦的是"不知道发什么",
  不是"没写众所周知的默认值"——此前缺 type 会直接失败并让模型重试一次。

判据 3 条(新增 `output_rules_test.go`):提示词不得含输出次数限制且必须显式授权 /
省略 type 时按 text 发送成功且 schema 的 required 只有 payload / 空 payload 仍被拦。

(cherry picked from commit 17ea7fd5f0)
2026-09-13 16:04:16 +08:00
f7c3a4e81d feat(channel): N1b —— 输出通道授权集合(三处过滤一致)+ 输出通道→目标 agent 的 inputch 解析
设计:docs/zh/resident-subagent-design.md §4.5(里程碑 N1b)。

## 输出通道授权集合(默认完整授权,父可收窄)

`AgentConfig.AllowedOutputs`(nil/空 = 完整授权)。三处过滤点必须一致,
否则会出现「列表里看不到、按名字还能调」的裂缝:

1. **工具表**:不为未授权的通道生成 output_send__X(模型看不到就不会调)
2. **列表工具**:output_list_channels 只列授权的
3. **调用点**:凭名字直调未授权的输出门必须被拒(纵深防御)

## 输出通道 → 目标 agent 的 inputch 解析

`ChannelRegistry.BindOutputTarget / ResolveOutputTarget`:
把输出通道解析成「目标 agent + 目标 inputch」,这是"输出可寻址到具体 agent"
(子→父、父→指定子)的**数据面**;真正的跨 agent 投递在里程碑 N4。
未登记的输出通道 ok=false —— 表示由传输层 device 自行处理(qq/webui 这类)。
已登记目标的输出通道,在 output_list_channels 里会标出「目标: <agent> / inputch <名字>」。

## 验收

`internal/agent/core/output_grant_test.go`(3 项):
- 默认完整授权:全部输出门生成 + 列表含全部
- 白名单收窄:三个过滤点同时生效(工具表 / 列表 / 直调被拒)
- 目标解析:绑定/解析、未登记由传输层处理、列表标出目标、空名报错

全仓 go test ./... 37 包 ok / 0 FAIL。
2026-09-13 09:13:19 +08:00
e218d0f100 fix(agent): 工具循环占位不再驱动重复发送,输出回执/子任务结果幂等
生产现象:单轮内 output_send__qq 被调用 34 次、持续 514 秒,直到 QQ 插件
自己的循环保险拒绝发送才停下(problem.md)。根因是多环节叠加,核心侧修四处:

1. 工具轮补位文案(process.go)
   通用占位「请根据以上工具结果继续。」对纯输出通道调用是错的:异步通道
   (qq/wechat)的回复只能经 output_send__* 交付,所以模型「已完成回复」的
   表达形式就是一个工具调用,紧随其后的「请继续」会被读成「还要再做一步」,
   而能做的「一步」恰好还是再发一条消息。
   改为按上一批工具的性质选文案:全部是 output_send__* 时补
   「若你的回复已完成,直接返回纯文本即可结束本轮,无需再调用任何工具。」
   同时每轮先移除旧占位再补一条,避免占位在 prompt 前缀里线性累积。
   (该占位是 zen 网关「最后一条必须是 user」的传输层附加物,HEAD 版本是
   无条件内联追加、从不移除。)

2. 输出成功回执(output.go)
   「已通过 [qq] 通道发送: map[status:sent]」这类富回执会被读成「这步成功,
   继续下一步」。成功改为只回极简标记。

3. proc 桥标量透传(internal/plugin/proc/plugin.go)
   插件返回 "ok" 时不再伪造 {status:sent} 覆盖插件真实返回值,否则只改
   output.go 不生效。

4. 子任务结果幂等(spawn.go)
   child_result 原先读到即删,而完成通知长期留在持久上下文里
   (formatMergedTimeline 每轮重新注入),第二次查询必然得到
   「不存在或已过期」这个永久失败信号,模型据此认为任务未完成而反复重试。
   改为保留结果 + delivered 标记,重复查询返回明确提示;结果按上限有界淘汰。

顺带:agent.go 去掉文档层显式向量器注入(TF-IDF 已内置为 fallback),
cmd/homed/main.go 同步 document.NewStore 的 tokenizer 参数。

测试:internal/agent/core/tooloop_test.go(5 例)、spawn_test.go(3 例)。
2026-09-10 20:36:39 +08:00
dev
b74ee15321 fix(cabi): output_send 等待真实发送结果,消除假成功(plan 11.1 / Part 0.1)
根因:CORE_REGISTER_OUTPUT_CH handler 无条件返回 {status:queued}+err=nil,
模型永远收到「已发送」,实际失败(如 meta 缺 user_id)只写日志,模型无法感知不会重试。
现网近 7 天成功 44 次、失败 2 次全部谎报成功。

改动:
- loader.go: 新增 awaitOutputResult(+可注入版 awaitOutputResultWith)+ outputSendTimeout=10s
  goroutine 执行 cgo 发送 + 带超时 channel 等结果 → sent / error / unconfirmed 三态
  handler 由 executeOutputSendTool 从 Go 侧调起,非 cgo 栈,不构成 cgo 嵌套
- output.go: executeOutputSendTool 识别 unconfirmed|queued,回报「发送结果未确认」而非「已发送」
- output_test.go: Success/Failure/Timeout 三用例

验证: go build exit 0; go test ./internal/plugin/... ./internal/agent/... 全绿
接口冻结: git diff third_party/homeagent-sdk/sdk/ 为空
2026-08-31 12:16:39 +08:00
bd0f84c1f7 fix: deduplicate assistant content in multi-tool turns to prevent premature loop exit
- process.go: only emit resp.Content on the first tool call per batch,
  subsequent assistant messages use empty content (serialized as null)
- provider.go: MarshalJSON outputs null content when empty with tool_calls
  to comply with DeepSeek/OpenAI expected format
- output.go: update parameter interface (payload/type/meta) to match
  tool definitions (uncommitted from previous refactor)
2026-07-22 17:05:13 +08:00
85992902d9 refactor: split agent.go into 12 files + add mcp_restart_server tool 2026-07-22 15:40:27 +08:00