refactor and add specs for the agent by @morriswinkler

This is a refactor, with specs, of #562.  @morriswinkler, I'd appreciate it if you could test this out!