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。
This commit is contained in:
Sakurasan committed 2026-10-26 00:54:46 +08:00
commit d5dac5a6fc
140 files changed
+26497

No files matched your search

+39
View File
@@ -0,0 +1,39 @@
// Package jsonl 提供 JSONL 的**容忍读取**:坏行跳过、**不设行长上限**。
//
// 为什么不直接用 bufio.Scanner:它有 64KB(bufio.MaxScanTokenSize)的默认行长上限,
// 超限时 Scan() 直接停下、Err() 返回 "bufio.Scanner: token too long" —— 整个文件
// 于是读不出来。这不是理论风险:20260916 有个会话因为一条 assistant 消息带 204KB
// 的 reasoning,整份 763KB 的会话在 WebUI 里**直接消失**(列表按"读不出来就跳过"
// 处理),历史也打不开。
//
// 所以这里用 bufio.Reader.ReadBytes 按行读,只在内存里持有当前这一行。
package jsonl
import (
"bufio"
"bytes"
"io"
)
// Each 逐行调用 fn(只传非空行,已去掉行尾换行)。坏行由 fn 自行决定怎么处理,
// 本函数不做解析判断。
//
// 返回的 error 只表示**读取失败**(IO),不含内容问题——内容层面的跳过是 fn 的事。
// 读到 EOF 视为正常结束(最后一行没有换行符也算)。
func Each(r io.Reader, fn func(line []byte)) error {
br := bufio.NewReader(r)
for {
line, err := br.ReadBytes('\n')
if len(line) > 0 {
if trimmed := bytes.TrimRight(line, "\r\n"); len(trimmed) > 0 {
fn(trimmed)
}
}
if err != nil {
if err == io.EOF {
return nil
}
return err
}
}
}
+58
View File
@@ -0,0 +1,58 @@
package jsonl
import (
"bytes"
"errors"
"strings"
"testing"
)
// TestEachLongLine:**回归**——超过 bufio.Scanner 默认 64KB 上限的行必须能读出来。
// 这正是那个会话消失的原因(一条 212KB 的 assistant 消息)。
func TestEachLongLine(t *testing.T) {
long := strings.Repeat("x", 300<<10) // 300KB
in := "{\"a\":1}\n" + "{\"b\":\"" + long + "\"}\n" + "{\"c\":3}"
var lines []int
if err := Each(strings.NewReader(in), func(line []byte) { lines = append(lines, len(line)) }); err != nil {
t.Fatalf("读取失败: %v", err)
}
if len(lines) != 3 {
t.Fatalf("行数 = %d, want 3(最后一行无换行也要算)", len(lines))
}
if lines[1] < 300<<10 {
t.Errorf("超长行被截断了: %d", lines[1])
}
}
// TestEachSkipsEmptyAndCRLF:空行跳过;CRLF 行尾要去掉。
func TestEachSkipsEmpty(t *testing.T) {
var got []string
in := "\n{\"a\":1}\r\n\n\n{\"b\":2}\n"
if err := Each(strings.NewReader(in), func(line []byte) { got = append(got, string(line)) }); err != nil {
t.Fatal(err)
}
if len(got) != 2 || got[0] != "{\"a\":1}" || got[1] != "{\"b\":2}" {
t.Errorf("实际: %q", got)
}
}
// errReader 模拟读失败。
type errReader struct{ n int }
func (e *errReader) Read(p []byte) (int, error) {
if e.n > 0 {
e.n--
copy(p, "{\"a\":1}\n")
return 8, nil
}
return 0, errors.New("boom")
}
// TestEachPropagatesIOError:IO 错误要如实返回,不能当成正常结束。
func TestEachPropagatesIOError(t *testing.T) {
err := Each(&errReader{n: 1}, func([]byte) {})
if err == nil || !strings.Contains(err.Error(), "boom") {
t.Errorf("应返回 IO 错误,实际 %v", err)
}
_ = bytes.MinRead
}