Well, the obvious building block is an LLM via some kind of harness like ollama. The rest is not that complicated, really! The heart of the loop is this function: