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。
67 lines
2.2 KiB
Go
67 lines
2.2 KiB
Go
// 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) }
|