hylo-reasoner-llm¶
Hylo LLM/VLM runtime components: client, planner, object choosers, VLM success judge (Ollama native or OpenAI-compatible endpoints)
Repository hylo-harness, adapters/hylo-reasoner-llm. Licence: Apache-2.0. Depends on: hylo-core, pillow>=10.
Registered entry points
| Group | Name | Object |
|---|---|---|
| choosers | chooser.llm |
hylo.reasoners.llm.chooser:LLMChooser |
| choosers | chooser.vlm |
hylo.reasoners.llm.vlm_chooser:VLMChooser |
| instruments | judge.vlm |
hylo.reasoners.llm.judge:VLMSuccessJudge |
| planners | planner.llm |
hylo.reasoners.llm.planner:LLMSubgoalPlanner |
| Module | Summary |
|---|---|
hylo.reasoners.llm |
LLM/VLM-backed reasoner components |
hylo.reasoners.llm.chooser |
LLM-backed object chooser: grounds a free-form instruction to one of the perceived objects |
hylo.reasoners.llm.client |
Minimal JSON-mode chat client for Ollama (native API) and OpenAI-compatible endpoints |
hylo.reasoners.llm.judge |
Zero-shot VLM success judge (RFC-0004 A3): a vision-language model looks at the final camera frames and the task |
hylo.reasoners.llm.planner |
LLM/VLM subgoal planner: a text LLM decomposes the instruction; a VLM checks completion from the camera |
hylo.reasoners.llm.vlm_chooser |
VLM object chooser with set-of-mark prompting |
hylo.reasoners.llm¶
LLM/VLM-backed reasoner components.
META
module-attribute
¶
META = {'contracts': {'choosers': 'hylo.chooser/v0.1', 'planners': 'hylo.planner/v0.1', 'instruments': 'hylo.instrument/v0.1'}, 'maturity': 'implemented', 'plugins': {'choosers/chooser.llm': {'weights': "the served model's own licence (e.g. a Qwen or GLM model run by Ollama)"}, 'choosers/chooser.vlm': {'weights': "the served model's own licence (e.g. a Qwen or GLM model run by Ollama)"}, 'planners/planner.llm': {'maturity': 'unverified', 'weights': "the served model's own licence (e.g. a Qwen or GLM model run by Ollama)"}, 'instruments/judge.vlm': {'maturity': 'unverified', 'notes': 'not yet calibrated against ground truth', 'weights': "the served model's own licence (e.g. a Qwen or GLM model run by Ollama)"}}}
hylo.reasoners.llm.chooser¶
LLM-backed object chooser: grounds a free-form instruction to one of the perceived objects.
Drop-in replacement for chooser.rule_color (same Chooser protocol), selected purely by config:
agent: {type: composable.object_reach, params: {chooser: {type: chooser.llm, params: {model: ...}}}}
SYSTEM
module-attribute
¶
SYSTEM = 'You ground natural-language instructions for a robot arm working on a table. You receive the instruction and a list of objects with their RGB colour (0-1 floats and hex) and position in metres. Decide which single object the instruction refers to. Reply with JSON only: {"object_id": "<one of the ids>", "rationale": "<one short sentence>"}.'
LLMChooser ¶
LLMChooser(model: str = 'qwen3.5:35b-a3b', base_url: str = 'http://127.0.0.1:11434', api: str = 'ollama', cache_dir: str | None = None, **client_kwargs: Any)
hylo.reasoners.llm.client¶
Minimal JSON-mode chat client for Ollama (native API) and OpenAI-compatible endpoints.
Standard library only. Responses are cached on disk by prompt hash so that evaluations are reproducible and re-runs do not hit the model; every result reports whether it was cached.
LLMError ¶
Bases: RuntimeError
LLMClient ¶
hylo.reasoners.llm.judge¶
Zero-shot VLM success judge (RFC-0004 A3): a vision-language model looks at the final camera frames and the task
instruction and says whether the task is complete. No training; trusted only after calibrate_judge against
simulator outcomes. Sees exactly what a real robot would record (no privileged state, no episode length).
instrument: {type: judge.vlm, params: {model: qwen3.5:35b-a3b, cameras: [agentview, wrist]}}
PROMPT
module-attribute
¶
PROMPT = 'You see the final state of a robot manipulation attempt: {views}.\nTask instruction: "{instruction}"\nDecide whether the task is fully completed in this final state. Every object named in the instruction must be in the\nstated place or state (e.g. inside the basket, on the plate, drawer closed, stove turned on). An object still held by\nthe gripper or merely near its target does not count.\nReply with JSON only: {{"completed": true or false, "confidence": <probability from 0 to 1 that the task is completed>,\n"reason": "<at most 20 words>"}}'
VIEW_NAMES
module-attribute
¶
VLMSuccessJudge ¶
hylo.reasoners.llm.planner¶
LLM/VLM subgoal planner: a text LLM decomposes the instruction; a VLM checks completion from the camera.
agent: {type: planner.subgoal, params: {inner: {...}, planner: {type: planner.llm, params: {...}}}}
PLAN_PROMPT
module-attribute
¶
PLAN_PROMPT = 'You plan for a robot arm controlled by a vision-language-action policy that was trained on short\ntabletop instructions such as "pick up the alphabet soup and place it in the basket", "open the top drawer of the\ncabinet", "put the bowl on the plate", "turn on the stove". Decompose the instruction into at most {max_subgoals}\nsequential sub-instructions in that style, one object or one action each. If it is already a single step, return it\nunchanged as the only sub-instruction. Keep object names exactly as written in the instruction.\nInstruction: "{instruction}"\nReply with JSON only: {{"subgoals": ["...", "..."], "rationale": "<one sentence>"}}'
DONE_PROMPT
module-attribute
¶
DONE_PROMPT = 'The image shows a robot workspace from a fixed camera. Has this sub-task been completed?\nSub-task: "{subgoal}"\nAnswer conservatively: only "true" if the end state is clearly visible.\nReply with JSON only: {{"done": true|false, "rationale": "<one short sentence>"}}'
LLMSubgoalPlanner ¶
LLMSubgoalPlanner(model: str = 'qwen3.5:35b-a3b', base_url: str = 'http://127.0.0.1:11434', api: str = 'ollama', camera: str = 'agentview', max_subgoals: int = 3, subgoal_max_steps: int = 260, plan_prompt: str = PLAN_PROMPT, done_prompt: str = DONE_PROMPT, cache_dir: str | None = None, **client_kwargs: Any)
client
instance-attribute
¶
hylo.reasoners.llm.vlm_chooser¶
VLM object chooser with set-of-mark prompting.
The model receives only the camera image, with each candidate object marked by its number; it never
sees colour values. Object positions are projected into the image with the pinhole parameters the
environment publishes in Observation.extra["camera_params"][camera].
PROMPT
module-attribute
¶
PROMPT = 'The image is a top-down view of a table with a robot arm. Candidate objects are marked with white number tags {marks}. Instruction: "{instruction}". Which numbered object does the instruction refer to? Reply with JSON only: {{"marker": <number>, "rationale": "<one short sentence about what you see>"}}.'
VLMChooser ¶
VLMChooser(model: str = 'qwen3.5:35b-a3b', base_url: str = 'http://127.0.0.1:11434', api: str = 'ollama', camera: str = 'top', cache_dir: str | None = None, **client_kwargs: Any)
project ¶
World points -> pixel (u, v) for a pinhole camera looking along its local -z (MuJoCo convention).