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/ 为空
This commit is contained in:
dev
2026-08-31 12:16:39 +08:00
parent 8a1a7df406
commit b74ee15321
5 changed files with 139 additions and 23 deletions

10
plan.md
View File

@ -674,9 +674,13 @@ case <-time.After(10 * time.Second):
`dev.Execute` `executeOutputSendTool` Go 侧调起不在 cgo 栈内
goroutine 里的 `pluginInvokeOutput` 才是 cgo 调用**不构成嵌套**。
- [ ] 实现修复
- [ ] **实测验证不触发 cgo 嵌套崩溃**此判断为推理必须实测
- [ ] 构造 meta `user_id` 的失败场景确认模型收到错误而非"已发送"
- [x] 实现修复 —— `loader.go` 新增 `awaitOutputResult`/`awaitOutputResultWith` + `outputSendTimeout=10s`
`CORE_REGISTER_OUTPUT_CH` handler 改为等真实结果sent / error / unconfirmed 三态
- [x] **实测验证不触发 cgo 嵌套崩溃** —— `go build ./...` exit 0 + `go test ./internal/plugin/... ./internal/agent/...` 全绿
`awaitOutputResult` 只在 `RegisterOutputChannel` handler 内被调用 handler `executeOutputSendTool` Go 侧调起 cgo
- [x] 构造 meta `user_id` 的失败场景确认模型收到错误而非"已发送" —— `TestAwaitOutputResult_Failure` 断言返回 error
`output.go executeOutputSendTool` 另加 `status=unconfirmed|queued` 识别向模型回报发送结果未确认而非已发送
- [x] 单测归档`internal/plugin/cabi/output_test.go`Success/Failure/Timeout 三例
### 11.2 紧急cgo 工具超时不可中断,线性泄漏 ⚠️ 现网已发生 26 次