Documentation
¶
Index ¶
- Constants
- func EstimateTokens(s string) int
- func FindSimilarFile(targetPath string) string
- func HasBinaryExtension(path string) bool
- func IsBinaryByContent(path string) (bool, error)
- func IsBinaryFile(path string) (bool, error)
- func IsBlockedDevicePath(path string) bool
- func IsWithinDir(path, dir string) bool
- func KillProcessGroup(cmd *exec.Cmd)
- func KillProcessGroupByPID(pid int)
- func NewRegistry() *registry
- func SanitizeJSON(raw string) string
- func SanitizeToolOutput(s string) string
- func ScanToolOutput(content string) string
- func SetSysProcAttr(cmd *exec.Cmd)
- func ShouldSkipDir(name string) bool
- func SuggestPathUnderCwd(targetPath string) string
- func WithReadState(ctx context.Context, store *ReadStateStore) context.Context
- type AskUserQuestion
- func (t *AskUserQuestion) ConcurrentSafe() bool
- func (t *AskUserQuestion) Description() string
- func (t *AskUserQuestion) Execute(ctx context.Context, params AskUserQuestionParams) (*ToolResult, error)
- func (t *AskUserQuestion) Name() string
- func (t *AskUserQuestion) Prompt() string
- func (t *AskUserQuestion) RequiresUserInteraction() bool
- func (t *AskUserQuestion) Schema() json.RawMessage
- type AskUserQuestionParams
- type DiffHunk
- type DiffLine
- type DiffLineKind
- type EditFile
- type EditFileParams
- type EnterPlanMode
- func (t *EnterPlanMode) ConcurrentSafe() bool
- func (t *EnterPlanMode) Description() string
- func (t *EnterPlanMode) Execute(ctx context.Context, params any) (*ToolResult, error)
- func (t *EnterPlanMode) Name() string
- func (t *EnterPlanMode) Prompt() string
- func (t *EnterPlanMode) RequiresUserInteraction() bool
- func (t *EnterPlanMode) Schema() json.RawMessage
- type ErasedTool
- func (e *ErasedTool) ConcurrentSafe() bool
- func (e *ErasedTool) Description() string
- func (e *ErasedTool) Execute(ctx context.Context, raw json.RawMessage) (*ToolResult, error)
- func (e *ErasedTool) ExecuteStreaming(ctx context.Context, raw json.RawMessage, chunkCb func(string)) (*ToolResult, error)
- func (e *ErasedTool) Name() string
- func (e *ErasedTool) Prompt() string
- func (e *ErasedTool) RequiresUserInteraction() bool
- func (e *ErasedTool) Schema() json.RawMessage
- func (e *ErasedTool) SupportsStreaming() bool
- func (e *ErasedTool) ToolTimeout() time.Duration
- type ErrorClass
- type ExitPlanMode
- func (t *ExitPlanMode) ConcurrentSafe() bool
- func (t *ExitPlanMode) Description() string
- func (t *ExitPlanMode) Execute(ctx context.Context, params any) (*ToolResult, error)
- func (t *ExitPlanMode) Name() string
- func (t *ExitPlanMode) Prompt() string
- func (t *ExitPlanMode) RequiresUserInteraction() bool
- func (t *ExitPlanMode) Schema() json.RawMessage
- type FileReadState
- type HunkResult
- type KillBackgroundTask
- func (t *KillBackgroundTask) ConcurrentSafe() bool
- func (t *KillBackgroundTask) Description() string
- func (t *KillBackgroundTask) Execute(ctx context.Context, p KillBackgroundTaskParams) (*ToolResult, error)
- func (t *KillBackgroundTask) Name() string
- func (t *KillBackgroundTask) Schema() json.RawMessage
- func (t *KillBackgroundTask) SupportsStreaming() bool
- type KillBackgroundTaskParams
- type Question
- type QuestionOption
- type ReadFile
- type ReadFileParams
- type ReadStateStore
- type Registry
- type SearchResult
- type Shell
- func (t *Shell) ConcurrentSafe() bool
- func (t *Shell) Description() string
- func (t *Shell) Execute(ctx context.Context, p ShellParams) (*ToolResult, error)
- func (t *Shell) ExecuteStreaming(ctx context.Context, p ShellParams, chunkCb func(string)) (*ToolResult, error)
- func (t *Shell) Name() string
- func (t *Shell) Prompt() string
- func (t *Shell) Schema() json.RawMessage
- func (t *Shell) SupportsStreaming() bool
- func (t *Shell) ToolTimeout() time.Duration
- type ShellParams
- type SkillExecutor
- type SkillLoadResult
- type SkillParams
- type SkillTool
- type StreamableTool
- type TodoCreate
- func (t *TodoCreate) ConcurrentSafe() bool
- func (t *TodoCreate) Description() string
- func (t *TodoCreate) Execute(ctx context.Context, params any) (*ToolResult, error)
- func (t *TodoCreate) Name() string
- func (t *TodoCreate) Prompt() string
- func (t *TodoCreate) RequiresUserInteraction() bool
- func (t *TodoCreate) Schema() json.RawMessage
- type TodoUpdate
- func (t *TodoUpdate) ConcurrentSafe() bool
- func (t *TodoUpdate) Description() string
- func (t *TodoUpdate) Execute(ctx context.Context, params any) (*ToolResult, error)
- func (t *TodoUpdate) Name() string
- func (t *TodoUpdate) Prompt() string
- func (t *TodoUpdate) RequiresUserInteraction() bool
- func (t *TodoUpdate) Schema() json.RawMessage
- type Tool
- type ToolError
- type ToolMeta
- type ToolResult
- type ToolSpec
- type ToolWithPrompt
- type ToolWithTimeout
- type TypedStreamableTool
- type TypedTool
- type UserInteractionTool
- type WebFetch
- type WebFetchParams
- type WebSearch
- type WebSearchParams
- type WriteFile
- type WriteFileParams
Constants ¶
const ( // MaxReadBytes 是 read_file 单次返回的最大字节数。 // 100KB ≈ 30K tokens(英文代码),对于绝大多数源文件足够。 MaxReadBytes = 100 << 10 // 100KB // FastPathMaxSize 是小文件快速路径的阈值。 // 小于此值的普通文件一次 ReadFile 读完,避免逐行 Scan 的异步开销。 FastPathMaxSize = 10 << 20 // 10MB MaxWriteBytes = 500 << 10 // 500KB — write_file 拒绝写入超过此大小的内容 MaxShellOutput = 100 << 10 // 100KB — shell 输出截断阈值 MaxShellLines = 3000 // shell 输出最大行数 MaxLineBytes = 4096 // shell 输出单行最大字节数,超长行截断 )
const ( DefaultShellTimeoutMs = 300000 MaxShellTimeoutMs = 1800000 )
const ( ErrKindFileNotFound = "file_not_found" ErrKindNoResults = "no_results" ErrKindInvalidArgs = "invalid_args" ErrKindCommandFailed = "command_failed" ErrKindCommandNotFound = "command_not_found" ErrKindCommandPermission = "command_permission_denied" ErrKindTimeout = "timeout" ErrKindNotDir = "not_dir" ErrKindBinaryFile = "binary_file" ErrKindMultipleMatch = "multiple_matches" ErrKindNoMatch = "no_match" ErrKindLargeFile = "large_file" )
Recoverable — LLM 可以修正
const ( ErrKindPermissionDenied = "permission_denied" ErrKindDiskFull = "disk_full" ErrKindUnknownTool = "unknown_tool" ErrKindSecurityViolation = "security_violation" )
Fatal — 不可恢复
const ( DefaultWebFetchMaxSize = 1 << 20 // 1MB MaxWebFetchMaxSize = 5 << 20 // 5MB DefaultWebFetchTimeoutMs = 30000 // 30s MaxWebFetchTimeoutMs = 120000 // 120s )
const ( DefaultWebSearchMaxResults = 10 MaxWebSearchMaxResults = 20 DefaultWebSearchTimeoutMs = 45000 // 45s MaxWebSearchTimeoutMs = 120000 // 120s )
Variables ¶
This section is empty.
Functions ¶
func EstimateTokens ¶
func FindSimilarFile ¶
--------------------------------------------------------------------------- FindSimilarFile — 在目标文件的父目录中查找相似文件名(仅当父目录存在时调用)。 返回相对路径(优先相对于 CWD);未找到足够相似的返回 ""。 阈值:max(3, len(name)/4),避免把无关文件当"相似"建议。
func HasBinaryExtension ¶
HasBinaryExtension 通过扩展名判断文件是否为已知二进制格式。
func IsBinaryByContent ¶
func IsBinaryFile ¶
func IsBlockedDevicePath ¶
IsBlockedDevicePath 检查路径是否为阻塞设备文件。
func IsWithinDir ¶
func KillProcessGroup ¶
KillProcessGroup kills the command's entire process group. On Unix, sends SIGKILL to -pgid. On Windows, does nothing (caller should use cmd.Process.Kill() instead).
func KillProcessGroupByPID ¶
func KillProcessGroupByPID(pid int)
KillProcessGroupByPID kills the process group identified by the given PID. On Unix, sends SIGKILL to -pid. On Windows, does nothing (caller should use os.Process.Kill() instead).
func SanitizeJSON ¶
SanitizeJSON 递归清洗 JSON 字符串中的所有键和值。
攻击者可在 JSON 的 key 中嵌入隐藏 Unicode 字符,纯字符串清洗(SanitizeToolOutput)不处理 key。
func SanitizeToolOutput ¶
SanitizeToolOutput 从工具输出中移除可用于 prompt injection 的隐藏 Unicode 字符。
三步清洗管线:
1. NFKC 正规化 — 折叠兼容性等價字符(如 fi→fi、K→K), 防止攻击者利用 Unicode 同形异义绕过关键词检测。 2. 主防御:Unicode 类别检测 — 移除 Cf(格式字符)、Co(私有使用区,含 TAG 字符)、 Cs(孤立代理)。 3. 辅助防御:显式区间 — 控制字符、Unicode 空白、非字符。
关键覆盖: - SOFT HYPHEN (U+00AD) — Cf,不可见,破坏 token 边界 - TAG 字符 (U+E0001, U+E0020+) — Co,HackerOne #3086545 的原始攻击向量 - WORD JOINER (U+2060) — Cf,零宽,影响 tokenization - 全部 16 个平面的 PUA — Co,自定义字体的走私通道 - 孤立代理 (U+D800-U+DFFF) — Cs,不应出现在合法 UTF-8 中
返回值:清洗后的字符串。 当无字符被移除时直接返回原字符串(避免不必要的内存分配)。
func ScanToolOutput ¶
ScanToolOutput 扫描工具输出中的 prompt injection 模式,返回标记文本。
Hook 社区规则(prompt-injection-defender)。 不作阻断——仅将命中的 WARNING 注入工具结果,改变 LLM 从"执行指令"到"警惕审查"的行为模式。
检测类别(优先级从高到低): 1. 指令覆盖 — "ignore previous instructions", "new system prompt:" 2. 角色扮演 — "you are DAN", "pretend you are" 3. 伪造上下文 — {"role":"system"}, "[system]", fake authority 4. 编码混淆 — 解码 \xNN/\uXXXX 与 base64 载荷后命中指令关键词才报警
返回:空字符串表示未命中,否则返回 WARNING 标记文本。
func SetSysProcAttr ¶
SetSysProcAttr sets process-group attributes for shell commands. On Unix, this enables Setpgid so the entire process group can be killed with a single signal. On Windows, this is a no-op.
func ShouldSkipDir ¶
func SuggestPathUnderCwd ¶
func WithReadState ¶ added in v0.4.3
func WithReadState(ctx context.Context, store *ReadStateStore) context.Context
WithReadState injects a ReadStateStore into ctx.
Types ¶
type AskUserQuestion ¶
type AskUserQuestion struct{}
AskUserQuestion 实现 TypedTool[AskUserQuestionParams]。 实际的用户交互由 Agent Loop 通过 TurnEvent + reply channel 完成, 工具自身的 Execute 仅在校验后返回占位结果(Loop 层会替换为实际答案)。
func (*AskUserQuestion) ConcurrentSafe ¶
func (t *AskUserQuestion) ConcurrentSafe() bool
func (*AskUserQuestion) Description ¶
func (t *AskUserQuestion) Description() string
func (*AskUserQuestion) Execute ¶
func (t *AskUserQuestion) Execute(ctx context.Context, params AskUserQuestionParams) (*ToolResult, error)
Execute 执行工具。 正常的用户交互流程由 Agent Loop 在 executeToolCalls 中拦截处理, 此方法仅在 Loop 未正确拦截时作为兜底返回。
func (*AskUserQuestion) Name ¶
func (t *AskUserQuestion) Name() string
func (*AskUserQuestion) Prompt ¶
func (t *AskUserQuestion) Prompt() string
Prompt 返回 ask_user_question 使用指南,由 Registry.FormatToolPrompts() 注入 C1 system prompt。 Prompt 返回使用指南,由 Registry.FormatToolPrompts() 注入 system prompt。
func (*AskUserQuestion) RequiresUserInteraction ¶
func (t *AskUserQuestion) RequiresUserInteraction() bool
func (*AskUserQuestion) Schema ¶
func (t *AskUserQuestion) Schema() json.RawMessage
type AskUserQuestionParams ¶
type AskUserQuestionParams struct {
Questions []Question `json:"questions"` // 1-4 个问题
}
AskUserQuestionParams 是 ask_user_question 工具的参数。
type DiffHunk ¶
type DiffHunk struct {
FilePath string // 所属文件路径(多文件编辑时标识 hunk 来源,空表示不适用)
OldStart int // 旧文件起始行号(1-based)
OldCount int // 旧文件覆盖行数
NewStart int // 新文件起始行号(1-based)
NewCount int // 新文件覆盖行数
Heading string // hunk 头部函数上下文(如 "func main() {")
Lines []DiffLine
// NoNewlineAtEOF 表示 hunk 末尾的旧文件或新文件不以换行结尾。
// 渲染时输出 "\ No newline at end of file" 标记(符合 POSIX unified diff 规范)。
NoNewlineAtEOF bool
}
DiffHunk 表示一个 diff 块(一段连续的变更 + 上下文)。
func ParseEditPreview ¶ added in v0.7.8
ParseEditPreview 解析 edit 工具 hunk 参数为结构化 diff(不应用文件), 用于权限审批框的改动预览。解析逻辑与 ApplyHunk 共用 parsePatchFiles / parseDiffHunk,保证预览展示的文件路径与行号和应用时一致。 返回 nil 表示无可预览内容(空 hunk 或全部解析失败)。
type DiffLine ¶
type DiffLine struct {
Kind DiffLineKind
Content string // 不含前缀的实际内容
OldNum int // 旧文件行号(0 = 不适用)
NewNum int // 新文件行号(0 = 不适用)
}
DiffLine 表示统一 diff 中的一行。
type DiffLineKind ¶
type DiffLineKind string
DiffLineKind 表示统一 diff 中一行的类型。
const ( DiffAdd DiffLineKind = "+" // 新增行 DiffDel DiffLineKind = "-" // 删除行 DiffCtx DiffLineKind = " " // 上下文行(未改动) DiffHeader DiffLineKind = "@" // hunk 头 )
type EditFile ¶ added in v0.4.3
type EditFile struct{}
func (*EditFile) ConcurrentSafe ¶ added in v0.4.3
func (*EditFile) Description ¶ added in v0.4.3
func (*EditFile) Execute ¶ added in v0.4.3
func (t *EditFile) Execute(ctx context.Context, p EditFileParams) (*ToolResult, error)
func (*EditFile) Schema ¶ added in v0.4.3
func (t *EditFile) Schema() json.RawMessage
type EditFileParams ¶ added in v0.4.3
type EnterPlanMode ¶
type EnterPlanMode struct{}
EnterPlanMode 实现 TypedTool[any]。 实际的状态切换由 Agent Loop 拦截处理,工具自身的 Execute 返回占位结果。
func (*EnterPlanMode) ConcurrentSafe ¶
func (t *EnterPlanMode) ConcurrentSafe() bool
func (*EnterPlanMode) Description ¶
func (t *EnterPlanMode) Description() string
func (*EnterPlanMode) Execute ¶
func (t *EnterPlanMode) Execute(ctx context.Context, params any) (*ToolResult, error)
Execute 返回占位结果。实际的状态切换由 Agent Loop 在 executeToolCalls 中拦截完成。
func (*EnterPlanMode) Name ¶
func (t *EnterPlanMode) Name() string
func (*EnterPlanMode) Prompt ¶
func (t *EnterPlanMode) Prompt() string
Prompt 返回 enter_plan_mode 的详细使用规则,由 Registry.FormatToolPrompts() 注入 C1。
func (*EnterPlanMode) RequiresUserInteraction ¶
func (t *EnterPlanMode) RequiresUserInteraction() bool
func (*EnterPlanMode) Schema ¶
func (t *EnterPlanMode) Schema() json.RawMessage
type ErasedTool ¶
type ErasedTool struct {
// contains filtered or unexported fields
}
ErasedTool 包装 TypedTool[P],实现 Tool 接口。 在 Execute 中统一完成 json.Unmarshal,工具实现者永远不需要手写。
func Wrap ¶
func Wrap[P any](t TypedTool[P]) *ErasedTool
Wrap 将 TypedTool[P] 包装为 Tool。 这是唯一的 json.Unmarshal 调用的位置 — 所有工具实现者不再需要手写反序列化。
func (*ErasedTool) ConcurrentSafe ¶
func (e *ErasedTool) ConcurrentSafe() bool
func (*ErasedTool) Description ¶
func (e *ErasedTool) Description() string
func (*ErasedTool) Execute ¶
func (e *ErasedTool) Execute(ctx context.Context, raw json.RawMessage) (*ToolResult, error)
func (*ErasedTool) ExecuteStreaming ¶
func (e *ErasedTool) ExecuteStreaming(ctx context.Context, raw json.RawMessage, chunkCb func(string)) (*ToolResult, error)
ExecuteStreaming 执行工具并将增量输出通过 chunkCb 推送。
func (*ErasedTool) Name ¶
func (e *ErasedTool) Name() string
func (*ErasedTool) Prompt ¶
func (e *ErasedTool) Prompt() string
func (*ErasedTool) RequiresUserInteraction ¶
func (e *ErasedTool) RequiresUserInteraction() bool
func (*ErasedTool) Schema ¶
func (e *ErasedTool) Schema() json.RawMessage
func (*ErasedTool) SupportsStreaming ¶
func (e *ErasedTool) SupportsStreaming() bool
SupportsStreaming 报告该工具是否支持增量输出推送。
func (*ErasedTool) ToolTimeout ¶
func (e *ErasedTool) ToolTimeout() time.Duration
ToolTimeout 返回工具自声明的超时。0 表示使用全局默认。
type ErrorClass ¶
type ErrorClass int
ErrorClass 区分错误的可恢复性。
const ( ErrorClassRecoverable ErrorClass = iota // LLM 可以自行修正 ErrorClassFatal // 必须终止 )
type ExitPlanMode ¶
type ExitPlanMode struct{}
ExitPlanMode 实现 TypedTool[any]。 实际的 plan 审批由 Agent Loop 拦截处理,工具自身的 Execute 返回占位结果。
func (*ExitPlanMode) ConcurrentSafe ¶
func (t *ExitPlanMode) ConcurrentSafe() bool
func (*ExitPlanMode) Description ¶
func (t *ExitPlanMode) Description() string
func (*ExitPlanMode) Execute ¶
func (t *ExitPlanMode) Execute(ctx context.Context, params any) (*ToolResult, error)
Execute 返回占位结果。实际的审批流程由 Agent Loop 在 executeToolCalls 中拦截完成。
func (*ExitPlanMode) Name ¶
func (t *ExitPlanMode) Name() string
func (*ExitPlanMode) Prompt ¶
func (t *ExitPlanMode) Prompt() string
Prompt 返回 exit_plan_mode 使用指南,由 Registry.FormatToolPrompts() 注入 C1 system prompt。 Prompt 返回使用指南,由 Registry.FormatToolPrompts() 注入 system prompt。
func (*ExitPlanMode) RequiresUserInteraction ¶
func (t *ExitPlanMode) RequiresUserInteraction() bool
func (*ExitPlanMode) Schema ¶
func (t *ExitPlanMode) Schema() json.RawMessage
type FileReadState ¶ added in v0.4.3
FileReadState records when a file was last read and its content at that time. Used by the edit tool to detect external modifications between read and edit.
type HunkResult ¶ added in v0.4.3
type HunkResult struct {
File string
Header string // @@ header text
Line int // line where hunk was applied (1-based), 0 if failed
Error string // empty if success
OldLines []string
NewLines []string
RawBody string // raw hunk body (lines after @@ header), for DiffHunk construction
// Failure diagnostics
FileSnippet string // file content around expected location
ClosestMatch string // closest-match hint
}
HunkResult reports the outcome of applying a single hunk.
func ApplyHunk ¶ added in v0.4.3
func ApplyHunk(ctx context.Context, path, hunkText string, readStates *ReadStateStore) ([]HunkResult, error)
ApplyHunk applies a multi-file multi-hunk patch to the filesystem. readStates is consulted for conflict detection; on success, read states are updated.
type KillBackgroundTask ¶
type KillBackgroundTask struct{}
func (*KillBackgroundTask) ConcurrentSafe ¶
func (t *KillBackgroundTask) ConcurrentSafe() bool
func (*KillBackgroundTask) Description ¶
func (t *KillBackgroundTask) Description() string
func (*KillBackgroundTask) Execute ¶
func (t *KillBackgroundTask) Execute(ctx context.Context, p KillBackgroundTaskParams) (*ToolResult, error)
func (*KillBackgroundTask) Name ¶
func (t *KillBackgroundTask) Name() string
func (*KillBackgroundTask) Schema ¶
func (t *KillBackgroundTask) Schema() json.RawMessage
func (*KillBackgroundTask) SupportsStreaming ¶
func (t *KillBackgroundTask) SupportsStreaming() bool
type KillBackgroundTaskParams ¶
type KillBackgroundTaskParams struct {
TaskID string `json:"task_id"`
}
type Question ¶
type Question struct {
Question string `json:"question"` // 完整问题,以 ? 结尾
Header string `json:"header"` // 简短标签,≤12 chars
Options []QuestionOption `json:"options"` // 2-4 项,label 唯一
MultiSelect bool `json:"multiSelect"` // 是否多选,默认 false
}
Question 是单个选择题。
type QuestionOption ¶
type QuestionOption struct {
Label string `json:"label"` // 显示文本,1-5 words
Description string `json:"description"` // 选项解释
}
QuestionOption 是选择题的单个选项。
type ReadFile ¶ added in v0.4.3
type ReadFile struct{}
func (*ReadFile) ConcurrentSafe ¶ added in v0.4.3
func (*ReadFile) Description ¶ added in v0.4.3
func (*ReadFile) Execute ¶ added in v0.4.3
func (t *ReadFile) Execute(ctx context.Context, p ReadFileParams) (*ToolResult, error)
func (*ReadFile) Prompt ¶ added in v0.4.3
Prompt 返回 read 工具使用指南,由 Registry.FormatToolPrompts() 注入 system prompt。
func (*ReadFile) Schema ¶ added in v0.4.3
func (t *ReadFile) Schema() json.RawMessage
type ReadFileParams ¶ added in v0.4.3
type ReadFileParams struct {
FilePath string `json:"file_path"` // 与 read_file 一致
Offset int `json:"offset"` // 0-based: 0 = 文件第一行
Limit int `json:"limit"` // 读取行数(0 = 不限)
Pattern string `json:"pattern"` // 可选:在文件中定位子串,窗口显示第一个匹配 ±context_lines
ContextLines int `json:"context_lines"` // 匹配行上下各显示的行数(默认 5,最大 50)
WorkingDir string `json:"working_dir"` // 工作目录(可选)
Outline bool `json:"outline"` // 返回符号大纲而非文件内容
}
type ReadStateStore ¶ added in v0.4.3
type ReadStateStore struct {
// contains filtered or unexported fields
}
ReadStateStore tracks read state per file, shared across turns within a session.
func NewReadStateStore ¶ added in v0.4.3
func NewReadStateStore() *ReadStateStore
NewReadStateStore creates an empty read state store.
func ReadStateFromContext ¶ added in v0.4.3
func ReadStateFromContext(ctx context.Context) *ReadStateStore
ReadStateFromContext extracts the ReadStateStore from ctx.
func (*ReadStateStore) Get ¶ added in v0.4.3
func (s *ReadStateStore) Get(path string) *FileReadState
Get returns the stored state for a file, or nil if not recorded.
func (*ReadStateStore) Record ¶ added in v0.4.3
func (s *ReadStateStore) Record(path, content string)
Record stores the read state for a file.
func (*ReadStateStore) Update ¶ added in v0.4.3
func (s *ReadStateStore) Update(path, content string)
Update refreshes the read state after a successful edit.
func (*ReadStateStore) Validate ¶ added in v0.4.3
func (s *ReadStateStore) Validate(path string) (ok bool, reason string)
Validate checks whether a file is safe to edit based on its read state. Returns ok=true if the file has been read and hasn't been modified externally. Returns a reason string when not ok.
type Registry ¶
type Registry interface {
Register(t Tool) // 注册工具;重复名称会 panic(编程错误)
List() []ToolSpec
Get(name string) (Tool, bool)
Execute(ctx context.Context, name string, input json.RawMessage) (*ToolResult, error)
IsStreamable(name string) bool
ExecuteStreaming(ctx context.Context, name string, input json.RawMessage, chunkCb func(string)) (*ToolResult, error)
// FormatToolPrompts 返回所有 ToolWithPrompt 工具的 C1 使用指南。
// 由 system prompt 构建器调用,实现“注册什么工具就注入什么指南”的按需组装。
FormatToolPrompts() string
}
Registry 管理所有已注册的工具。
func NewChildRegistry ¶ added in v0.6.0
NewChildRegistry 创建共享父级的分层注册表。 用途:per-session 隔离(如 ACP 每个 session 的 MCP 工具只对自身可见; session 关闭时丢弃 child 即天然反注册,无需修改父级)。 shadow 语义:本地注册与父级同名的工具时,List 以本地为准(父级同名条目被遮蔽)。
type SearchResult ¶
type Shell ¶
type Shell struct {
AllowBg bool // true for "bash" (main agent), false for "bash_subagent"
// SandboxMgr 沙箱管理器(可选)。注入后,按 context 中 per-command
// SandboxStatus 决定是否用 bwrap 包装命令;nil 或不可用 → 原样执行。
SandboxMgr *sandbox.SandboxManager
// contains filtered or unexported fields
}
func (*Shell) ConcurrentSafe ¶
func (*Shell) Description ¶
Description 仅描述 API 契约。行为约束(使用规则、策略)见 Prompt(), 由 Registry.FormatToolPrompts() 注入 C1 system prompt。
func (*Shell) Execute ¶
func (t *Shell) Execute(ctx context.Context, p ShellParams) (*ToolResult, error)
func (*Shell) ExecuteStreaming ¶
func (t *Shell) ExecuteStreaming(ctx context.Context, p ShellParams, chunkCb func(string)) (*ToolResult, error)
ExecuteStreaming 执行 shell 命令并将增量输出通过 chunkCb 实时推送。 使用文件 polling 替代管道读取:每 500ms 读取输出文件的新增内容,// 逐行 push ToolCallStream 到 TUI。后台命令同样支持。
func (*Shell) Prompt ¶
Prompt 返回 shell 使用行为约束,由 Registry.FormatToolPrompts() 注入 C1 system prompt。 Prompt 返回使用指南,由 Registry.FormatToolPrompts() 注入 system prompt。
func (*Shell) Schema ¶
func (t *Shell) Schema() json.RawMessage
func (*Shell) SupportsStreaming ¶
SupportsStreaming 报告 bash 工具支持增量输出推送。
func (*Shell) ToolTimeout ¶
ToolTimeout 声明 Shell 工具的最大超时(30 分钟)。 这样 effectiveTimeout 会使用此值而非 Loop 默认值(5 min),// 确保用户传入的 timeout_ms 参数在 (5 min, 30 min] 区间内能正常生效。
type ShellParams ¶
type SkillExecutor ¶
type SkillExecutor interface {
Load(name, args string) (*SkillLoadResult, error)
}
SkillExecutor 加载并渲染 skill。 skill 包实现此接口,tool 包通过接口消费,消除 tool → skill 的编译期依赖。
type SkillLoadResult ¶
type SkillLoadResult struct {
Body string // 渲染后的 body(变量已替换、!`cmd` 已执行、附属文件清单已追加)
DirPath string // SKILL.md 所在目录
}
SkillLoadResult 是 SkillExecutor 加载 skill 后的结果。
type SkillParams ¶
type SkillParams struct {
Name string `json:"name"` // skill 名称
Arguments string `json:"arguments"` // 传入 skill 的参数(可选)
}
SkillParams 是 skill 工具的参数。
type SkillTool ¶
type SkillTool struct {
// contains filtered or unexported fields
}
SkillTool 让 LLM 可以调用用户定义的 skill。 实现 TypedTool[SkillParams]。
func (*SkillTool) ConcurrentSafe ¶
func (*SkillTool) Description ¶
func (*SkillTool) Execute ¶
func (t *SkillTool) Execute(ctx context.Context, p SkillParams) (*ToolResult, error)
func (*SkillTool) Schema ¶
func (t *SkillTool) Schema() json.RawMessage
type StreamableTool ¶
type StreamableTool interface {
SupportsStreaming() bool
ExecuteStreaming(ctx context.Context, raw json.RawMessage, chunkCb func(string)) (*ToolResult, error)
}
StreamableTool 是类型擦除后的流式工具接口。 Loop 在执行前通过 type assertion 检测此接口,决定走 streaming 路径还是普通 Execute。
type TodoCreate ¶
type TodoCreate struct{}
func (*TodoCreate) ConcurrentSafe ¶
func (t *TodoCreate) ConcurrentSafe() bool
func (*TodoCreate) Description ¶
func (t *TodoCreate) Description() string
func (*TodoCreate) Execute ¶
func (t *TodoCreate) Execute(ctx context.Context, params any) (*ToolResult, error)
func (*TodoCreate) Name ¶
func (t *TodoCreate) Name() string
func (*TodoCreate) Prompt ¶
func (t *TodoCreate) Prompt() string
func (*TodoCreate) RequiresUserInteraction ¶
func (t *TodoCreate) RequiresUserInteraction() bool
func (*TodoCreate) Schema ¶
func (t *TodoCreate) Schema() json.RawMessage
type TodoUpdate ¶
type TodoUpdate struct{}
func (*TodoUpdate) ConcurrentSafe ¶
func (t *TodoUpdate) ConcurrentSafe() bool
func (*TodoUpdate) Description ¶
func (t *TodoUpdate) Description() string
func (*TodoUpdate) Execute ¶
func (t *TodoUpdate) Execute(ctx context.Context, params any) (*ToolResult, error)
func (*TodoUpdate) Name ¶
func (t *TodoUpdate) Name() string
func (*TodoUpdate) Prompt ¶
func (t *TodoUpdate) Prompt() string
func (*TodoUpdate) RequiresUserInteraction ¶
func (t *TodoUpdate) RequiresUserInteraction() bool
func (*TodoUpdate) Schema ¶
func (t *TodoUpdate) Schema() json.RawMessage
type Tool ¶
type Tool interface {
Name() string
Description() string
Schema() json.RawMessage
ConcurrentSafe() bool
Execute(ctx context.Context, raw json.RawMessage) (*ToolResult, error)
}
Tool 是 Registry 存储和 Loop 调用的统一接口。 每个 TypedTool[P] 通过 Wrap() 包装为 Tool,json.Unmarshal 由 ErasedTool 统一处理。
type ToolError ¶
type ToolError struct {
Class ErrorClass // 分类
Kind string // "file_not_found", "permission_denied", "invalid_args" ...
Message string // 人类可读描述,会返回给 LLM
Cause error // 原始 error,不对外暴露
}
ToolError 封装工具执行错误。
type ToolMeta ¶
type ToolMeta struct {
Duration time.Duration // 执行耗时
FilePath string // 操作涉及的文件路径(如有)
ExitCode int // shell 命令退出码(-1 表示不适用)
LineCount int // 输出行数
ByteCount int // 输出字节数
// BackgroundTaskID 后台任务 ID(非空表示命令在后台执行)。
BackgroundTaskID string
// LogPath 输出日志路径(文件 fd 模式下的输出文件路径)。
LogPath string
// DiffHunks 为 edit_file / write_file 等工具提供的结构化 diff,供 TUI 渲染带行号的统一 diff 视图。
// nil 表示不适用(非编辑类工具或发生错误)。
DiffHunks []DiffHunk
}
ToolMeta 携带结构化元数据。
type ToolResult ¶
type ToolResult struct {
Content string // 文本输出(发送给 LLM)
Meta ToolMeta // 元数据(供 Loop 和其他组件使用)
Error *ToolError
ToolCallID string // LLM 工具调用 ID,由 Loop 填充(工具实现者不感知)
}
ToolResult 封装工具执行结果。
type ToolSpec ¶
type ToolSpec struct {
Name string `json:"name"`
Description string `json:"description"`
Parameters json.RawMessage `json:"parameters"` // JSON Schema 参数定义
Prompt string `json:"-"` // 工具使用指南(注入 system message,不进入 function description)
}
ToolSpec 是 Tool 的轻量描述,发送给 LLM 做 function calling。 字段和 JSON tag 对齐 OpenAI Chat Completions / DeepSeek API 的 tools[].function 格式。
type ToolWithPrompt ¶
type ToolWithPrompt interface {
Prompt() string
}
ToolWithPrompt 是可选接口,由需要注入使用指南的工具实现。 Prompt() 返回工具的使用指南(When to Use / NOT / 示例等), 由 Loop 在启动时注入 system message,与 Description 分离。 Description 保持简短(~30 token),Prompt 可包含详细规则。
type ToolWithTimeout ¶
ToolWithTimeout 是可选接口,由需要非默认超时的工具实现。 返回 0 → 使用全局默认值 (DefaultToolTimeout)。
type TypedStreamableTool ¶
type TypedStreamableTool[P any] interface { SupportsStreaming() bool ExecuteStreaming(ctx context.Context, params P, chunkCb func(string)) (*ToolResult, error) }
TypedStreamableTool 由支持增量输出推送的工具实现。 Wrap() 自动检测并桥接到 ErasedTool,json.Unmarshal 集中处理。
type TypedTool ¶
type TypedTool[P any] interface { Name() string Description() string Schema() json.RawMessage // JSON Schema for input parameters ConcurrentSafe() bool // true → 可并行;false → 必须串行 Execute(ctx context.Context, params P) (*ToolResult, error) }
TypedTool 是工具实现者关心的类型安全接口。 P 是工具的参数结构体,例如 ReadFileParams。
type UserInteractionTool ¶
type UserInteractionTool interface {
RequiresUserInteraction() bool
}
UserInteractionTool 是可选接口,由需要阻塞式用户交互的工具实现。 Loop 在执行前检查此接口;若返回 true,则工具不经过权限检查和普通执行路径, 改为通过 UserResponder 进行阻塞式交互。
type WebFetch ¶
type WebFetch struct {
// contains filtered or unexported fields
}
func (*WebFetch) ConcurrentSafe ¶
func (*WebFetch) Description ¶
func (*WebFetch) Execute ¶
func (t *WebFetch) Execute(ctx context.Context, p WebFetchParams) (*ToolResult, error)
func (*WebFetch) Prompt ¶
Prompt 返回 web_fetch 使用指南和跨工具引用,由 Registry.FormatToolPrompts() 注入 C1。 Prompt 返回使用指南,由 Registry.FormatToolPrompts() 注入 system prompt。
func (*WebFetch) Schema ¶
func (t *WebFetch) Schema() json.RawMessage
type WebFetchParams ¶
type WebSearch ¶
type WebSearch struct {
// contains filtered or unexported fields
}
func (*WebSearch) ConcurrentSafe ¶
func (*WebSearch) Description ¶
func (*WebSearch) Execute ¶
func (t *WebSearch) Execute(ctx context.Context, p WebSearchParams) (*ToolResult, error)
func (*WebSearch) Prompt ¶
Prompt 返回 web_search 使用指南和跨工具引用,由 Registry.FormatToolPrompts() 注入 C1。 Prompt 返回使用指南,由 Registry.FormatToolPrompts() 注入 system prompt。
func (*WebSearch) Schema ¶
func (t *WebSearch) Schema() json.RawMessage
type WebSearchParams ¶
type WriteFile ¶
type WriteFile struct{}
func (*WriteFile) ConcurrentSafe ¶
func (*WriteFile) Description ¶
func (*WriteFile) Execute ¶
func (t *WriteFile) Execute(ctx context.Context, p WriteFileParams) (*ToolResult, error)
func (*WriteFile) Prompt ¶
Prompt 返回 write_file 使用约束,由 Registry.FormatToolPrompts() 注入 C1 system prompt。
func (*WriteFile) Schema ¶
func (t *WriteFile) Schema() json.RawMessage