Documentation
¶
Overview ¶
Package toolparse 提供外部 CLI 工具的结构化输出解析与事实黑板自动落库。
设计见 docs/工具结构化输出与事实黑板打通-改造档案.md §四:
- 输出层:executor 挂钩层把平台独占输出标志注入 argv(模型不可覆盖), 纯 stdout 模式直接产出结构化内容,落文件模式(-o/-of/--log-xml)由 挂钩层把结构化文件内容并入 stdout 后再交给解析器(§4.3 runner 契约)。
- 解析层:按工具名分发到注册的 Parser,产出 Result(关键字段 + 事实候选 + raw_ref)。
- 落库层:store.go 把事实候选写入 project_facts / assets(同步、失败不阻断、fail-closed)。
解析失败一律回退现状(原文 + 截断 + spill),不落任何事实(§4.7)。
Index ¶
- Constants
- Variables
- func InjectedTools() []string
- func Manifest() core.Manifest
- func NewCapability(core.Deps) (core.Capability, error)
- func Register(p Parser)
- func RegisteredTools() []string
- func RenderParseError(tool string) string
- func RenderReceipt(res *Result, recorded int) string
- func Sluggify(s string) string
- func ValidateFactKey(factKey string) error
- type Capability
- type ConcludeEnvelope
- type FactCandidate
- type FactLink
- type Injection
- type Parser
- type Result
- type TargetAware
Constants ¶
const ConcludeMaxFacts = 20
ConcludeMaxFacts 解析层硬顶(提示词限 12 条,此处放余量防灌库)。
const MaxFactsIndexEntries = 12
MaxFactsIndexEntries facts_index 展示条数上限(超限截断 + 计数兜底,§5.5 双写率口径依赖它存在)。
const MaxReceiptBytes = 2048
MaxReceiptBytes 回执硬上限(§4.6:2KB)。
const TmpDirPlaceholder = "<TMPDIR>"
注入目录模板占位符(挂钩层执行前替换为实际 tmpdir)。
Variables ¶
var ValidCategories = map[string]bool{ "finding": true, "chain": true, "exploit": true, "poc": true, "target": true, "auth": true, "infra": true, "business": true, }
ValidCategories 既有 fact_key category 前缀白名单(禁止新增,见档案 §十)。
Functions ¶
func NewCapability ¶
func NewCapability(core.Deps) (core.Capability, error)
NewCapability builds the parser capability.
func RenderParseError ¶
RenderParseError 解析失败回退时的回执(§4.7:标 parse_error,模型据此知道该次未落库)。
func RenderReceipt ¶
RenderReceipt 渲染模型可见回执文本(Content[0].Text 用)。 规则:超出 MaxReceiptBytes 时先裁 facts_index,再整体截断加尾注。
func ValidateFactKey ¶
ValidateFactKey 校验 fact_key 前缀与整体形态(与既有 ValidateFactKey 同口径, 见 internal/database/project_fact_edges.go;此处为 toolparse 侧前置校验,落库前还会再过一次 DB 层)。
Types ¶
type Capability ¶
type Capability struct{}
Capability exposes the structured-output parsers as a tool. It turns one external CLI tool's raw stdout into key fields and fact candidates, so the agent reads structure instead of scraping text.
func (*Capability) Manifest ¶
func (c *Capability) Manifest() core.Manifest
Manifest implements core.Capability.
type ConcludeEnvelope ¶
type ConcludeEnvelope struct {
Facts []FactCandidate `json:"facts"`
Residual string `json:"residual"`
}
ConcludeEnvelope 收尾轮回执信封。category 不在信封字段里——由 fact_key 前缀推导 (键即分类的单一事实源,与 ValidCategories 白名单同口径)。
func ParseConcludeOutput ¶
func ParseConcludeOutput(text string) (*ConcludeEnvelope, error)
ParseConcludeOutput 从收尾轮回复文本解析增量事实信封(fail-closed)。 候选 JSON 依次尝试:``` 围栏块 → 顶层平衡对象 → 整段文本;候选必须含 "facts" 字段 (防把无关 JSON/工具回显误收为信封)。全部失败返回 error,不落任何事实; 单条事实不合格只丢弃该条(NormalizeFact 同口径),不影响其余条目。
type FactCandidate ¶
type FactCandidate struct {
FactKey string `json:"fact_key"` // 必须符合既有约定:<category>/<slug>(§4.5 规则 1)
Category string `json:"category"` // finding|target|infra|auth|...(既有枚举,禁止新增)
Summary string `json:"summary"` // 「什么+在哪+如何验证」
Body string `json:"body"` // 复现细节(命令/证据摘录;原始输出不写入,只挂 raw_ref)
Confidence string `json:"confidence"` // tentative|confirmed(解析器不得直接写升级判定)
Links []FactLink `json:"links,omitempty"`
}
FactCandidate 结构化 → 事实黑板的一条候选(落库层消费)。 字段口径与 upsert_project_fact 工具一致(见 internal/app/project_fact_tools.go)。
func NormalizeFact ¶
func NormalizeFact(f FactCandidate) (FactCandidate, error)
NormalizeFact 落库前规范化:校验 fact_key/category/confidence 合法值,裁剪异常字段。 返回规范化后的候选;不合格返回 error(fail-closed:宁可不落,不错落)。
type Injection ¶
type Injection struct {
Tool string
// Args 追加进 argv 的平台独占标志(filterDangerousFlags 之后、exec 之前,模型不可覆盖)。
Args []string
// ResultFileRel 相对注入目录的结果文件(目录由挂钩层生成:<workspace>/toolparse/<executionID>/)。
// 该文件内容由挂钩层并入 stdout 供解析器消费;空 = 无落盘文件(纯 stdout 模式)。
ResultFileRel string
}
Injection 描述一次工具调用的平台注入:追加 argv 与执行后需并入 stdout 的文件。
func InjectionFor ¶
InjectionFor 返回某工具的注入描述(未注册 → nil,保持现状零行为变化)。
func (*Injection) ResolveArgs ¶
ResolveArgs 把注入 argv 里的目录占位符替换为实际 tmpdir(幂等)。
func (*Injection) ResolveResultPath ¶
ResolveResultPath 返回结果文件的绝对路径(无 ResultFileRel 返回 "")。
type Parser ¶
type Parser interface {
// Match 判定该解析器是否处理这次调用(按工具名 + 已注入的输出标志)。
Match(tool string, argv []string) bool
// Parse 解析原始输出(runner 契约见 §4.3:stdout 已含该模式最完整的结构化内容)。
Parse(stdout, stderr string, rawRef string) (*Result, error)
}
Parser 解析器接口。实现须对畸形/截断输入安全(fail-closed):解析失败返回 OK=false 且 Facts 为空,不得从半截文本猜事实。
type Result ¶
type Result struct {
Tool string `json:"tool"`
OK bool `json:"ok"`
Fields map[string]any `json:"fields"` // 关键字段(端口/状态码/技术栈…),只放标量与计数
Facts []FactCandidate `json:"facts"` // 事实候选
RawRef string `json:"raw_ref"` // 原始证据落盘路径(read_file 可回读)
Err string `json:"err,omitempty"`
}
Result 一个工具的解析结果。
type TargetAware ¶
type TargetAware interface {
NeedsTarget() bool
}
TargetAware 需要目标 URL 才能生成事实键的解析器(arjun/sqlmap 等结构化内容里无 host)。 executor 挂钩层会把注入 argv 中的目标 URL 以 "TARGET: <url>\n" 前缀并入 stdout。