Concepts¶
Hellig has four moving parts. Each is a tiny dataclass or Protocol that you can replace independently.
Compiler¶
A Compiler turns natural-language source into a Program — an ordered list
of Instructions.
class Compiler(Protocol):
def compile(self, source: str, context: dict | None = None) -> Program: ...
Hellig ships with StubCompiler, a deterministic line-based parser used by
default so the framework runs without any external LLM. In production
you’ll typically plug in an LLM-backed compiler — see
Extending Hellig.
Program & Instructions¶
A Program is a sequence of Instructions drawn from a tiny ISA:
| Op | Meaning |
|---|---|
say |
print a message to the user (supports {var} substitution) |
ask |
ask the user a question, bind the reply to a variable |
call |
call a registered agent with a prompt |
tool |
invoke a registered tool function with kwargs |
set |
bind a literal value into scope |
done |
halt execution |
Every instruction can read from and write to the runtime's scope — the flat dictionary of variables threaded through a session. Full details in the instruction set reference.
Runtime¶
The Runtime is the interpreter. It owns:
- agents: name →
Agentlookup for thecallop - tools: name → callable for the
toolop - io: how to
sayandask(defaults toClickIO— your terminal) - scope: variables produced and consumed by instructions
The runtime can pause mid-program to call back to the user via io.ask. That
is what makes Hellig feel conversational rather than batch.
Session¶
A Session is the multi-turn glue. It pairs a compiler with a runtime and
keeps a history of turns. Scope persists across turns, so a later turn can
reference variables bound by an earlier one.
from hellig import Session
s = Session() # default StubCompiler + Runtime + ClickIO
s.turn("? city -> city") # turn 1: asks the user
s.turn(": You picked {city}") # turn 2: uses scope from turn 1
Agent¶
Agents are the workers call instructions dispatch to. The base class is
intentionally tiny:
runtime is any callable that takes a prompt and returns a string — wrap any
LLM client you like. The default echoes the prompt back, which is enough for
demos and tests.
IO adapter¶
IO decouples the runtime from where input/output goes:
ClickIO— terminal, the defaultScriptedIO— deterministic queue of answers for tests, with a transcript
Implement say(text) and ask(prompt) -> str to write your own (web UI,
chat platform, voice, etc.).