internal/tool — 工具定義與註冊表

Tool 型別、Registry、Provider 介面
套件:internal/tool/(definitions.go + code_comment.go + code_search.go + file_read*.go + file_find.go)

大方向

internal/tool 定義「評審工具」的抽象與六個內建工具的實作。核心是 definitions.goTool 是工具的不可變名稱,Registry 是名稱 → provider 的對照,Provider 介面定義單一能力(讀檔、搜碼…)。MCP 動態工具也透過 Dynamic 建構進入同一 registry。


1. 工具識別

Tool 型別與內建常數 definitions.go六個內建工具名稱 + Unknown 哨兵。

Tool{name: "task_done"} 等七個常數(含 Unknown)。OfName 依名稱反查;IsReserved 檢查名稱是否與內建衝突(MCP 註冊時用);Dynamic(name) 為 MCP 動態工具建構非保留名稱的 Tool——保留名會 panic。

2. Provider 介面

Provider 介面 · Registry · Register()/Get()/Freeze() definitions.go工具能力抽象與名稱→provider 註冊表。

Provider 只有兩個方法:Tool()(回傳實作的工具名)與 Execute(ctx, args)(執行並回傳結果字串)。Registrymap[string]Provider——Register 把 provider 掛到名稱下,Freeze 鎖定禁止再改(組裝完成後呼叫)。

教學重點:Freeze 之後 registry 就是併發安全的唯讀——這是「建置期組裝、執行期唯讀」的 Go 慣用模式。

3. 錯誤處理

NotAvailableMsg · ErrToolNotFound definitions.go未知工具回傳固定訊息而非崩潰。

工具名不在 registry 時,llmloop 回傳 NotAvailableMsg("Error: Tool not found…")給模型——這讓 --tools 停用工具是安全的:模型會收到標準錯誤訊息而不是 crash。

4. 實作(節選)

code_search.go · file_read.go · file_find.go · code_comment.go internal/tool六個工具的具體實作。

code_searchgit grep(pathspec、gitignore);file_read 讀變更後檔案一段(500 行上限);file_findgit ls-files/git ls-tree 列候選並 basename 子串匹配;code_comment 收集評論並派發到 CommentWorkerPool 做行解析。每個都是 Execute(ctx, args map[string]any) (string, error) 的薄實作。

看完這頁你應該能說出Tool/Registry/Provider 三者的關係、Freeze 的併發安全意義、Dynamic 如何讓 MCP 工具安全進入 registry、以及 NotAvailableMsg 為何重要。

下一步:internal/mcp 或回程式碼對照