ollama/agent/policy.go
ParthSareen 7703a00ade refactor(agent): introduce RunPolicy and drop --hidethinking
Replaces the scattered auto-approve plumbing (ApprovalManager.AutoApprove,
chatPermissionMode, opts.AutoApproveTools, and the approvalHandlerAutoApproves
type-switch) with a single RunPolicy value object carrying ToolMode
(Review/FullAccess/Disabled), an ApprovalPolicy strategy, and MaxToolRounds.
Mode is derived once per surface via resolveAgentRunPolicy, and the TUI toggles
it in place via RunPolicyState.

These two changes land together because they share struct-field plumbing in
agent_tui.go: the --hidethinking removal drops HideThinking from the same
gofmt-realigned AgentTUIOptions/runOptions literals that gain the Policy field,
so splitting them would produce intermediate states that do not build.

Also drops the now-unused PermissionNotice() and RunPolicyState.SetPolicy,
and simplifies the headless tool-resolution block.
2026-06-25 13:20:14 -07:00

92 lines
1.7 KiB
Go

package agent
import "sync"
type ToolMode int
const (
ToolModeReview ToolMode = iota
ToolModeFullAccess
ToolModeDisabled
)
type RunPolicy struct {
ToolMode ToolMode
ApprovalPolicy ApprovalPolicy
// MaxToolRounds limits consecutive model/tool cycles.
// Zero uses the default guard; negative disables the guard for tests or
// special callers.
MaxToolRounds int
}
func (p RunPolicy) UsesTools() bool {
switch p.ToolMode {
case ToolModeReview, ToolModeFullAccess:
return true
default:
return false
}
}
func (p RunPolicy) Tools(registry *Registry) *Registry {
if !p.UsesTools() {
return nil
}
return registry
}
func (p RunPolicy) ApprovalHandler(prompter ApprovalPrompter) ApprovalHandler {
if p.ToolMode == ToolModeFullAccess {
return AutoAllowApproval{}
}
policy := p.ApprovalPolicy
if policy == nil {
policy = DefaultApprovalPolicy{}
}
return NewApprovalManager(ApprovalManagerOptions{
Policy: policy,
Prompter: prompter,
})
}
func (p RunPolicy) ReviewApprovalHandler(prompter ApprovalPrompter) ApprovalHandler {
policy := p.ApprovalPolicy
if policy == nil {
policy = DefaultApprovalPolicy{}
}
return NewApprovalManager(ApprovalManagerOptions{
Policy: policy,
Prompter: prompter,
})
}
type RunPolicyState struct {
mu sync.Mutex
policy RunPolicy
}
func NewRunPolicyState(policy RunPolicy) *RunPolicyState {
return &RunPolicyState{policy: policy}
}
func (s *RunPolicyState) Policy() RunPolicy {
if s == nil {
return RunPolicy{}
}
s.mu.Lock()
defer s.mu.Unlock()
return s.policy
}
func (s *RunPolicyState) ToolMode() ToolMode {
return s.Policy().ToolMode
}
func (s *RunPolicyState) SetToolMode(mode ToolMode) {
if s == nil {
return
}
s.mu.Lock()
defer s.mu.Unlock()
s.policy.ToolMode = mode
}