Programmatic API¶
Everything hg does is available as plain Python. Use this when you want to
embed Hellig in a larger app or test agents deterministically.
Minimal example¶
from hellig import Agent, Runtime, Session, StubCompiler
session = Session(
compiler=StubCompiler(default_agent="main"),
runtime=Runtime().register_agent(Agent(name="main")),
)
session.turn("? What's your name? -> name\n: Hi {name}!")
print(session.runtime.scope["name"])
Deterministic tests with ScriptedIO¶
ScriptedIO replays a queue of answers and records a transcript, so unit
tests don't need a TTY.
from hellig import Agent, Runtime, Session, StubCompiler
from hellig.io import ScriptedIO
io = ScriptedIO(answers=["Hang", "cats"])
runtime = (
Runtime(io=io)
.register_agent(Agent(name="main", runtime=lambda p, **_: f"<{p}>"))
)
session = Session(compiler=StubCompiler(), runtime=runtime)
session.turn("? Name? -> name\n: Hi {name}!")
session.turn(
"? Topic? -> topic\n"
"@main write about {topic} -> essay\n"
": Done. essay={essay}"
)
assert runtime.scope == {
"name": "Hang",
"topic": "cats",
"essay": "<write about cats>",
}
assert ("say", "Hi Hang!") in io.transcript
Building a program by hand¶
Skip the compiler entirely when you already know the steps:
from hellig import Instruction, Program, Runtime, Agent
from hellig.io import ScriptedIO
program = Program(
source="(manual)",
instructions=[
Instruction.ask("city", "city"),
Instruction.call("weather", "forecast for {city}", "fc"),
Instruction.say("Forecast: {fc}"),
Instruction.done(),
],
)
io = ScriptedIO(answers=["Beijing"])
runtime = Runtime(io=io).register_agent(
Agent(name="weather", runtime=lambda p, **_: f"sunny in {p}"),
)
runtime.execute(program)
print(io.transcript)
Registering tools¶
Tools are any Python callable. The runtime calls them with rendered string kwargs:
Then from the stub compiler:
Inspecting a session¶
turn.program.to_text() returns the human-readable opcode dump that
hg compile prints.