Yes, the debugger is programmable. The following manual section discusses how to detect determinism at the Exit port:
If you want to test in your code whether a goal left choicepoints behind, there is no need to resort to the debugger, you can use the trick:
call_det(Goal, Det) :-
call_cleanup(Goal, Det0=true),
( var(Det0) -> Det = nondet ; Det = det ).
This will unify Det with det if no choicepoints were left begind, and with nondet otherwise.