Monsters are animated in server frame steps and their AI and movement runs at the same pace.
Monster movement relies on mmove_t and mframe_t structures. The first defines a move in terms of which frame sequence is to be executed. The latter defines the actual frame sequence. Each monster has its own frame sequences, which you will find in each monster's C-file. The monsterinfo_t, of the monster's edict_t, has a currentmove pointer that points to a predefined mmove_t.
In addition to specifying which model to use for the monster in each frame, the mframe_t specifies the AI-function and think function to be called each frame. Thus, AI can easily be scripted into the monster's animation sequences. Commonly, the AI function pointer points to a function inside g_ai.c. The mframe_t also contains a dist attribute, which tells how far the monster will move the next frame.
It is common that a monster specifies ai_walk as the aifunc for a frame. That function tries to move the monster a distacnce in the monster's moving direction. A lot of checks takes place first to see if the monster is blocked by something, but if the path is clear the SV_movestep function will update the monster's entity_state_t's origin.
Every monster move starts in the RunFrame function. It will call the think function of the monster further down the call graph. The think function of a monster always points at monster_think. From there, the game DLL will call M_MoveFrame. M_MoveFrame increases the frame number and calls both the AI-function and the think function of the current frame.