MCPcopy Create free account
hub / github.com/astercloud/aster / WrapToolCall

Method WrapToolCall

pkg/middleware/hitl.go:170–247  ·  view source on GitHub ↗

WrapToolCall 拦截工具调用,请求人工审核

(ctx context.Context, req *ToolCallRequest, handler ToolCallHandler)

Source from the content-addressed store, hash-verified

168
169// WrapToolCall 拦截工具调用,请求人工审核
170func (m *HumanInTheLoopMiddleware) WrapToolCall(ctx context.Context, req *ToolCallRequest, handler ToolCallHandler) (*ToolCallResponse, error) {
171 // 检查是否需要审核
172 interruptCfg, needsApproval := m.interruptConfigs[req.ToolName]
173 if !needsApproval {
174 // 不需要审核,直接执行
175 return handler(ctx, req)
176 }
177
178 hitlLog.Info(ctx, "tool requires approval", map[string]any{"tool": req.ToolName})
179
180 // 构建审核请求
181 reviewRequest := &ReviewRequest{
182 ActionRequests: []ActionRequest{
183 {
184 ToolCallID: req.ToolCallID,
185 ToolName: req.ToolName,
186 Input: req.ToolInput,
187 Message: interruptCfg.Message,
188 },
189 },
190 ReviewConfigs: []InterruptConfig{*interruptCfg},
191 }
192
193 // 获取人工决策
194 decisions, err := m.getApproval(ctx, reviewRequest)
195 if err != nil {
196 return &ToolCallResponse{
197 Result: map[string]any{
198 "ok": false,
199 "error": fmt.Sprintf("approval request failed: %v", err),
200 },
201 }, nil
202 }
203
204 if len(decisions) == 0 {
205 return &ToolCallResponse{
206 Result: map[string]any{
207 "ok": false,
208 "error": "no decision received",
209 },
210 }, nil
211 }
212
213 decision := decisions[0]
214
215 // 处理决策
216 switch decision.Type {
217 case DecisionApprove:
218 hitlLog.Info(ctx, "tool approved", map[string]any{"tool": req.ToolName})
219 return handler(ctx, req)
220
221 case DecisionEdit:
222 hitlLog.Info(ctx, "tool approved with edited input", map[string]any{"tool": req.ToolName})
223 // 使用编辑后的参数
224 editedReq := *req
225 editedReq.ToolInput = decision.EditedInput
226 return handler(ctx, &editedReq)
227

Calls 3

getApprovalMethod · 0.95
handlerFunction · 0.85
InfoMethod · 0.65