Take JSON in a param
When an event needs more than a line of text from the agent, such as a plan with a list of steps, give the event a param of type: json. The agent then passes a JSON value, and a JSON Schema tells it the shape of the value.
Steps
The steps use a schema of the value, in a JSON file beside the machine. This schema describes a plan as an object with a list of steps:
.smllm/plan.schema.json
{
"type": "object",
"properties": {
"steps": { "type": "array", "items": { "type": "string" }, "minItems": 1 }
},
"required": ["steps"]
}
The config lists the machine. The machine declares the param in the event’s params, with type: json and the schema’s path, relative to the machine file:
.smllm/config.toml
[machines]
files = ["plan.smllm.yaml"]
.smllm/plan.smllm.yaml
id: plan
description: Plan a change as a list of steps, then carry it out.
initial: PLAN
meta:
smllm: 1
events:
planned:
description: Fire with the plan, after you write it.
params:
type: object
properties:
plan:
type: json
description: The plan, as an object with its steps in order.
schema: plan.schema.json
required: [plan]
done:
description: Fire after the last step.
states:
PLAN:
meta: { entryPoint: true }
entry: { type: prompt, params: { text: "Write a plan, then fire planned with it." } }
on:
planned: WORK
WORK:
entry: { type: prompt, params: { text: "Carry out the plan, one step at a time." } }
on:
done: DONE
DONE:
type: final
schema can also hold the schema itself as a map, in place of a path. A schema declares draft-07 or 2020-12 in $schema, or no draft, which smllm reads as 2020-12.
-
Check the machine.
smllm validatereads the schema, and reports an error when the schema is invalid or names a file that smllm can’t read:$ smllm validate 0 errors, 0 warnings, 0 info -
Enter the machine, as the agent does:
$ smllm fire --session sm-nqvfvw enter --param stateMachine=plan <smllm> session sm-nqvfvw · plan › PLAN · instance i-0ekd6p Arrived by: enter (new instance) Params: stateMachine = "plan" <instructions> Write a plan, then fire planned with it. </instructions> </smllm>sm-nqvfvwis the key of the session. Your key differs.The events list shows the param as a JSON value, with its schema, so the agent knows what to pass:
<smllm> session sm-nqvfvw · plan › PLAN · instance i-0ekd6p Fire one event: smllm({ session: "sm-nqvfvw", event, params }) <events> - planned: Fire with the plan, after you write it. plan (required, a JSON value, schema: {"type":"object","properties":{"steps":{"type":"array","items":{"type":"string"},"minItems":1}},"required":["steps"]}): The plan, as an object with its steps in order. - yield: Stop for now and stay in PLAN. note (optional): What you are waiting for. - pause: Put instance i-0ekd6p aside and return to idle. - unmatched: The request fits none of these; handle it from idle, then resume. </events> </smllm> -
Fire the event with a JSON value. The agent passes the value as JSON in the smllm tool’s
params. From the shell,--paramreads the text after=as JSON, so quote it for the shell. smllm checks the value against the schema, and refuses a value that doesn’t match:$ smllm fire --session sm-nqvfvw planned --param 'plan={"steps": []}' <smllm> session sm-nqvfvw · plan › PLAN · instance i-0ekd6p error: planned param plan doesn't match its schema. At /steps: [] has less than 1 item Fire one event: smllm({ session: "sm-nqvfvw", event, params }) <events> - planned: Fire with the plan, after you write it. plan (required, a JSON value, schema: {"type":"object","properties":{"steps":{"type":"array","items":{"type":"string"},"minItems":1}},"required":["steps"]}): The plan, as an object with its steps in order. - yield: Stop for now and stay in PLAN. note (optional): What you are waiting for. - pause: Put instance i-0ekd6p aside and return to idle. - unmatched: The request fits none of these; handle it from idle, then resume. </events> </smllm> [exit 1]Each sentence after the error names a part of the value that fails, by its JSON path. A value that matches the schema moves the instance on:
$ smllm fire --session sm-nqvfvw planned --param 'plan={"steps": ["Write a test that fails", "Fix the parser"]}' <smllm> session sm-nqvfvw · plan › WORK · instance i-0ekd6p Arrived by: planned from PLAN Params: plan = {"steps":["Write a test that fails","Fix the parser"]} <instructions> Carry out the plan, one step at a time. </instructions> </smllm>A command action or guard of the transition reads the value as compact JSON text from the variable
SMLLM_PARAM_PLAN, the param’s name in upper snake case.
Troubleshooting
- smllm refuses the event with
planned param plan must be a JSON value: the text isn’t JSON. Quote a string as JSON, such asplan="\"one step\"", and quote the whole param for your shell. - smllm refuses the event with
planned param plan doesn't match its schema: the value is JSON, but a part of it fails the schema. Correct each part that the error names by its JSON path, and fire the event again. - A string param with
schema, or a JSON param withenumorpattern, is an error:schemabelongs only to a JSON param, andenumandpatternonly to a string param.