Class: OllamaAgent::Core::LoopDetector
- Inherits:
-
Object
- Object
- OllamaAgent::Core::LoopDetector
- Defined in:
- lib/ollama_agent/core/loop_detector.rb
Overview
Detects when the agent is stuck in a repeating tool-call loop.
Strategy: keep a sliding window of (tool_name + args_fingerprint) tokens. If the most-recent window pattern appears THRESHOLD or more times in the accumulated history, we declare a loop.
Constant Summary collapse
- DEFAULT_WINDOW =
number of consecutive calls to treat as one pattern
4- DEFAULT_THRESHOLD =
how many times the pattern must repeat
2
Instance Attribute Summary collapse
-
#history ⇒ Object
readonly
Returns the value of attribute history.
Instance Method Summary collapse
-
#initialize(window: DEFAULT_WINDOW, threshold: DEFAULT_THRESHOLD) ⇒ LoopDetector
constructor
A new instance of LoopDetector.
-
#loop_detected? ⇒ Boolean
Returns true when the recent pattern has repeated enough times.
-
#loop_summary ⇒ Object
Human-readable description of the detected loop.
-
#record!(tool_name, args = {}) ⇒ Object
Record a tool call.
- #reset! ⇒ Object
Constructor Details
#initialize(window: DEFAULT_WINDOW, threshold: DEFAULT_THRESHOLD) ⇒ LoopDetector
Returns a new instance of LoopDetector.
16 17 18 19 20 |
# File 'lib/ollama_agent/core/loop_detector.rb', line 16 def initialize(window: DEFAULT_WINDOW, threshold: DEFAULT_THRESHOLD) @window = window.to_i.clamp(1, 32) @threshold = threshold.to_i.clamp(2, 16) @history = [] end |
Instance Attribute Details
#history ⇒ Object (readonly)
Returns the value of attribute history.
14 15 16 |
# File 'lib/ollama_agent/core/loop_detector.rb', line 14 def history @history end |
Instance Method Details
#loop_detected? ⇒ Boolean
Returns true when the recent pattern has repeated enough times.
30 31 32 33 34 35 36 37 38 39 40 41 |
# File 'lib/ollama_agent/core/loop_detector.rb', line 30 def loop_detected? return false if @history.size < @window * @threshold pattern = @history.last(@window) matches = 0 (@history.size - @window + 1).times do |i| matches += 1 if @history[i, @window] == pattern end matches >= @threshold end |
#loop_summary ⇒ Object
Human-readable description of the detected loop.
44 45 46 47 48 49 |
# File 'lib/ollama_agent/core/loop_detector.rb', line 44 def loop_summary return nil unless loop_detected? pattern = @history.last(@window) "Loop detected: pattern [#{pattern.join(" → ")}] repeated #{@threshold}+ times" end |
#record!(tool_name, args = {}) ⇒ Object
Record a tool call. Should be called before executing each tool.
25 26 27 |
# File 'lib/ollama_agent/core/loop_detector.rb', line 25 def record!(tool_name, args = {}) @history << fingerprint(tool_name, args) end |
#reset! ⇒ Object
51 52 53 |
# File 'lib/ollama_agent/core/loop_detector.rb', line 51 def reset! @history.clear end |