Regarding triggers vs. threads... the two are not mutually exclusive. That said, constant polling of the environment is computationally expensive if done incorrectly but also yields some more subtle behavior than having things entirely trigger-based. There are pros and cons. You can also have "immediate action" triggers show up as high-priority decisions in the landscape (so to speak) so that they can't be ignored.
Actually, this is akin to my current thought, and kind of coincides with my lame attempts at 'memory' or 'historical environment knowledge'. As an agent blunders through the environment, all manipulatable objects and their locations are stored along with a timestamp. The timestamp is used to degrade the knowledge 'value' over time so that a berry bush at X one hour ago has more 'value' then an equal (size, type, distance, etc) berry bush recorded at an earlier time. When accessing this array, I divide the values into 2 groups: Immediate Vicinity (Line of Sight) and Long Distance. Now, as Goals are formulated, any objects required to achieve a particular Goal are stored AND then the 'memory' is evaluated and the objects in memory have their values additionally adjusted upwards in importance, becoming 'triggers'. Then, as movement occurs, any trigger that comes into view causes the AI to re-evaluate the goal in which that object is a part of and possibly altering the current goal to incorporate manipulation of this trigger object into the plan. I refer to these 'triggers' as Dynamic Triggers. I like the idea of Dynamic Triggers and the Timestamps allow me to put an upper limit on the amount of memory required, flushing out 'old' info.
BUT, implementation of this has been more memory/computationally intensive then I would like, and seems to me kind of 'clunky' - still debugging and re-balancing values which I fear has been the majority of time involved coding.