05AB1E, 14 12 11 bytes
Îvy'^QDŠ‹+<
Port of @Sp3000's Gol><> answer.
NOTE: @Grimy already posted a shorter 8 bytes alternative for 05AB1E, so make sure to upvote him!
Try it online or verify all test cases.
Explanation:
Î # Push 0 (later mentioned as `r`) and the input-string
v # Loop over the characters of the input:
y'^Q '# Does the current character equal "^"?
# (results in 1 for truthy; 0 for falsey - later mentioned as `b`)
D # Duplicate this result `b`
Š # Triple swap (`r`,`b`,`b`) to (`b`,`r`,`b`)
‹ # Check if the boolean `b` is smaller than the result-integer `r`
# (again results in 1 for truthy; 0 for falsey)
+ # Add them together
< # Decrease this by 1
# (Implicitly output the result-integer `r` after the loop)