Files
Sakurasan d5dac5a6fc feat: AutoZero 通用 Agent 框架(从 AutoGo 五阶段拆分完成)
llm(三协议 Provider)/ session(JSONL 持久化)/ tools(Registry、围栏、
builtin、computer)/ cdp(browser)/ skills / mcp / agent(循环、两级压缩、
编排、审批门控)+ 底座 jsonl/textx/execx/diag/scratch/spill/imagecache。

产品装配代码(config 桥接、schedule 工具、memory/plan/retro/prompt)
留在 AutoGo,宿主接入方式见 MIGRATION.md。
2026-10-26 00:54:46 +08:00

67 lines
2.2 KiB
Go
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
// Package diag 提供进程级的诊断输出去向。
//
// 为什么需要它:TUI 跑在 alt-screen 下,**任何**直接写终端的行为都会打穿界面——
// 项目里已有这条约定(见 tui.Run 的注释:"服务日志写文件而非 stderr:alt-screen 下
// 任何直接写终端的行为都会打穿界面")。但工具层与协议客户端没有 agent 的 Opt.Stderr
// 可用,直接 fmt.Fprintf(os.Stderr, ...) 就会打穿。
//
// 所以:库层写诊断信息一律经过这里;入口(TUI)在进入全屏前把去向换成日志文件。
// 默认仍是 os.Stderr——CLI / headless / -serve 下本来就该直接看到。
//
// 注意区分两类东西:
// - **我们自己的**诊断 → diag.Printf
// - **子进程的** stderr → diag.Indirect()(子进程的 stderr 只能在启动时给一次,
// 而那时入口还没拿到日志文件,所以要把"解析去向"推迟到每次写入)
package diag
import (
"fmt"
"io"
"os"
"sync"
)
var (
mu sync.Mutex
w io.Writer = os.Stderr
)
// SetWriter 替换诊断去向(传 nil 表示丢弃)。TUI 应在进入 alt-screen 前调用。
func SetWriter(nw io.Writer) {
if nw == nil {
nw = io.Discard
}
mu.Lock()
w = nw
mu.Unlock()
}
// Writer 返回当前去向。
func Writer() io.Writer {
mu.Lock()
defer mu.Unlock()
return w
}
// Printf 按当前去向写一条诊断。
func Printf(format string, args ...any) {
_, _ = fmt.Fprintf(Writer(), format, args...)
}
// Println 按当前去向写一行诊断。
func Println(args ...any) {
_, _ = fmt.Fprintln(Writer(), args...)
}
// Indirect 返回一个"写入时才解析去向"的 writer,给子进程的 cmd.Stderr 用。
//
// 不能直接传 Writer():子进程的 stderr 只在启动时赋值一次,而启动那一刻入口还没
// 拿到日志文件(TUI 是在启动服务之前才建日志文件的),传值等于把 os.Stderr 钉死。
// Indirect 把解析推迟到每次 Write;exec 见到非 *os.File 的 writer 会自建管道并拷贝,
// 于是入口随后的重定向对已启动的子进程同样生效。
func Indirect() io.Writer { return indirect{} }
type indirect struct{}
func (indirect) Write(p []byte) (int, error) { return Writer().Write(p) }