5510ea8f5a
Add an opt-in human approval gate so Agent runs pause before executing MCP tools that operators flag as dangerous, surface an approval card in the chat UI, and only resume after the user approves (optionally with edited args) or rejects. Backend - New mcp_tool_approvals table + repo/service to mark per-tool approval required (PG migration 000042 + sqlite init). - approval.Gate coordinates RequestAndWait / Resolve with sync.Once delivery, configurable timeout, and Redis Pub/Sub fan-out so multi- replica deployments work without sticky sessions. - MCPTool.Execute integrates the gate; uses a round-level ApprovalCtx (without the per-tool 60s timeout) for the wait, and re-derives a fresh 60s exec ctx after approval so CallTool keeps a full window. - New SSE response types (tool_approval_required / _resolved) and EventBus events plumb approval state to AgentStreamDisplay. - REST: list/set per-tool approval flag, resolve pending approval. - Configurable via agent.tool_approval_timeout_seconds (yaml) or WEKNORA_AGENT_TOOL_APPROVAL_TIMEOUT env (accepts seconds or Go duration). Frontend - MCP settings: per-tool "require approval" switch on the test panel. - Chat: ToolApprovalCard renders the pause point with editable JSON args, validation feedback, mm:ss countdown that turns warning/danger near deadline, and a resolved state that retains context. - i18n strings added for zh-CN / en-US / ko-KR / ru-RU. Docs - docs/zh/mcp-approval.md covering behavior, config, API, deployment considerations (Redis cross-instance, restart limitations).
41 lines
1.2 KiB
Go
41 lines
1.2 KiB
Go
package tools
|
|
|
|
import (
|
|
"context"
|
|
|
|
"github.com/Tencent/WeKnora/internal/event"
|
|
)
|
|
|
|
type execCtxKey struct{}
|
|
|
|
// ToolExecContext is attached to context during agent tool execution (per tool call).
|
|
type ToolExecContext struct {
|
|
SessionID string
|
|
AssistantMessageID string
|
|
RequestID string
|
|
ToolCallID string
|
|
EventBus *event.EventBus
|
|
// ApprovalCtx is the parent ctx WITHOUT defaultToolExecTimeout; used when the tool
|
|
// must wait for human approval that may exceed normal tool exec timeout (issue #1173).
|
|
// Falls back to the per-tool execCtx when nil.
|
|
ApprovalCtx context.Context
|
|
}
|
|
|
|
// WithToolExecContext returns ctx that carries ToolExecContext for MCP approval and similar features.
|
|
func WithToolExecContext(ctx context.Context, meta *ToolExecContext) context.Context {
|
|
if meta == nil {
|
|
return ctx
|
|
}
|
|
return context.WithValue(ctx, execCtxKey{}, meta)
|
|
}
|
|
|
|
// ToolExecFromContext returns metadata attached by the agent engine, if any.
|
|
func ToolExecFromContext(ctx context.Context) (*ToolExecContext, bool) {
|
|
v := ctx.Value(execCtxKey{})
|
|
if v == nil {
|
|
return nil, false
|
|
}
|
|
meta, ok := v.(*ToolExecContext)
|
|
return meta, ok && meta != nil
|
|
}
|