* feat(agent): add smart loop detection for stuck agents (#16)
Detect when agents repeat the same tool calls or text outputs in a
sliding window. Three modes: warn (inject nudge, terminate on 2nd hit),
terminate (immediate stop), or custom callback. Fully opt-in via
`loopDetection` on AgentConfig — zero overhead when unconfigured.
* fix(agent): support async onLoopDetected callbacks and prevent orphaned tool_use events
- Await onLoopDetected callback result so async functions work correctly
instead of silently falling through to 'continue'
- Move loop detection before yielding tool_use events so terminate mode
never emits tool_use without a matching tool_result
* fix(agent): reset loopWarned on recovery and rename maxRepeatedToolCalls to maxRepetitions
- Reset loopWarned flag when the agent stops repeating, so a future
loop gets a fresh warning cycle instead of immediate termination
- Rename maxRepeatedToolCalls → maxRepetitions since the threshold
applies to both tool call and text output repetition detection
* test(agent): add tests for async callback, warn recovery, and injected warning text
- Verify async onLoopDetected callback is awaited correctly
- Verify loopWarned resets after recovery, giving fresh warning cycle
- Verify WARNING TextBlock is injected into user message content