Per OAS 26.1.0 ll. 1351–1359, InputMessageNode is documented as "wait for a user input and restarts after getting it", with the output typed as user-input string.
For typed HITL gates this is restrictive. Real-world HITL surfaces include:
- Operator picks one of N items from a structured list (wants
{ selectedId: string, label: string })
- Operator fills a schema-driven form (wants a typed object)
- Operator approves a structured payload (wants
{ decision: "approve" | "edit" | "reject", patch?: object })
- Operator selects from an enum with rich display labels (wants
{ value: string, displayLabel: string })
Today's pattern
Implementations encode JSON in the string output and parse-on-receipt. Consequences:
- Bypasses schema validation that the spec could otherwise enforce
- Every downstream node consuming the output must know the encoding convention
- Loses the type information that would let UIs auto-render the gate from the spec alone
- Different runtimes invent slightly different envelope shapes — same OAS file can produce subtly different operator UX across implementations
Proposed extension
Add an optional payload_schema (JSON Schema) and payload output to InputMessageNode:
{
"component_type": "InputMessageNode",
"id": "operator_pick",
"payload_schema": {
"type": "object",
"required": ["selectedId"],
"properties": {
"selectedId": { "type": "string" },
"displayLabel": { "type": "string" }
}
},
"outputs": [
{ "title": "payload", "type": "object" }
]
}
When payload_schema is present, the resumed task's payload MUST validate against it; otherwise the run transitions to failure. UI runtimes can auto-render the gate from the schema.
Back-compat: when payload_schema is absent, behavior matches today's string-output contract.
Alternative
Document the JSON-envelope convention as the recommended pattern in the spec text. Even formalising the workaround would unblock convergence — different implementations would at least agree on the envelope shape.
The spec primitive is the cleaner answer but either move is better than the current silence.
Per OAS 26.1.0 ll. 1351–1359,
InputMessageNodeis documented as "wait for a user input and restarts after getting it", with the output typed as user-input string.For typed HITL gates this is restrictive. Real-world HITL surfaces include:
{ selectedId: string, label: string }){ decision: "approve" | "edit" | "reject", patch?: object }){ value: string, displayLabel: string })Today's pattern
Implementations encode JSON in the string output and parse-on-receipt. Consequences:
Proposed extension
Add an optional
payload_schema(JSON Schema) andpayloadoutput toInputMessageNode:{ "component_type": "InputMessageNode", "id": "operator_pick", "payload_schema": { "type": "object", "required": ["selectedId"], "properties": { "selectedId": { "type": "string" }, "displayLabel": { "type": "string" } } }, "outputs": [ { "title": "payload", "type": "object" } ] }When
payload_schemais present, the resumed task'spayloadMUST validate against it; otherwise the run transitions to failure. UI runtimes can auto-render the gate from the schema.Back-compat: when
payload_schemais absent, behavior matches today's string-output contract.Alternative
Document the JSON-envelope convention as the recommended pattern in the spec text. Even formalising the workaround would unblock convergence — different implementations would at least agree on the envelope shape.
The spec primitive is the cleaner answer but either move is better than the current silence.