Skip to content

[Spec] InputMessageNode should support typed payloads beyond string #184

Description

@groganz

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.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions