plexus.cli.procedure.lua_dsl.primitives.human module

Human Primitive - Human-in-the-Loop (HITL) operations.

Provides: - Human.approve(opts) - Request yes/no approval (blocking) - Human.input(opts) - Request free-form input (blocking) - Human.review(opts) - Request review with options (blocking) - Human.notify(opts) - Send notification (non-blocking) - Human.escalate(opts) - Escalate to human (blocking)

class plexus.cli.procedure.lua_dsl.primitives.human.HumanPrimitive(chat_recorder, execution_context, hitl_config: Dict[str, Any] | None = None)

Bases: object

Manages human-in-the-loop operations for procedures.

Enables procedures to: - Request approval from humans - Get input from humans - Send notifications - Escalate issues

All blocking methods support timeouts and defaults.

Initialize Human primitive.

Args:

chat_recorder: ProcedureChatRecorder for recording messages execution_context: ExecutionContext for blocking HITL operations hitl_config: Optional HITL declarations from YAML

__init__(chat_recorder, execution_context, hitl_config: Dict[str, Any] | None = None)

Initialize Human primitive.

Args:

chat_recorder: ProcedureChatRecorder for recording messages execution_context: ExecutionContext for blocking HITL operations hitl_config: Optional HITL declarations from YAML

approve(options: Dict[str, Any] | None = None) bool

Request yes/no approval from human (BLOCKING).

Args:
options: Dict with:
  • message: str - Message to show human

  • context: Dict - Additional context

  • timeout: int - Timeout in seconds (None = no timeout)

  • default: bool - Default if timeout (default: False)

  • config_key: str - Reference to hitl: declaration

Returns:

bool - True if approved, False if rejected/timeout

Example (Lua):
local approved = Human.approve({

message = “Deploy to production?”, context = {environment = “prod”}, timeout = 3600, default = false

})

if approved then

deploy()

end

escalate(options: Dict[str, Any] | None = None) None

Escalate to human (BLOCKING).

Stops workflow execution until human resolves the issue. Unlike approve/input/review, escalate has NO timeout - it blocks indefinitely until a human manually resumes the procedure.

Args:
options: Dict with:
  • message: str - Escalation message

  • context: Dict - Error context

  • severity: str - Severity level (info/warning/error/critical)

  • config_key: str - Reference to hitl: declaration

Returns:

None - Execution resumes when human resolves

Example (Lua):
if attempts > 3 then
Human.escalate({

message = “Cannot resolve automatically”, context = {attempts = attempts, error = last_error}, severity = “error”

}) – Workflow continues here after human resolves

end

async flush_recordings() None

Flush all queued messages to chat recorder.

This is called by the runtime after workflow execution to record all Human.notify() messages to the chat session.

input(options: Dict[str, Any] | None = None) str | None

Request free-form input from human (BLOCKING).

Args:
options: Dict with:
  • message: str - Prompt for human

  • placeholder: str - Input placeholder

  • timeout: int - Timeout in seconds

  • default: str - Default if timeout

  • config_key: str - Reference to hitl: declaration

Returns:

str or None - Human’s input, or None if timeout with no default

Example (Lua):
local topic = Human.input({

message = “What topic?”, placeholder = “Enter topic…”, timeout = 600

})

if topic then

State.set(“topic”, topic)

end

notify(options: Dict[str, Any] | None = None) None

Send notification to human (NON-BLOCKING).

Args:
options: Dict with:
  • message: str - Notification message (required)

  • content: str - Rich markdown content (optional, overrides message in UI)

  • details: List[Dict] - Collapsible sections with title and content

  • level: str - info, warning, error (default: info)

  • context: Dict - Additional context (deprecated, use details instead)

Example (Lua):

– Simple notification Human.notify({

message = “Processing complete”

})

– Rich notification with details Human.notify({

message = “Phase 2 complete”, content = “Status: Phase 2 processing finishednnProcessed 150 items successfully”, details = {

{title = “Statistics”, content = “Success: 148n**Failed**: 2n**Duration**: 5 min”}, {title = “Next Steps”, content = “Starting phase 3 validation”}

}

})

review(options: Dict[str, Any] | None = None) Dict[str, Any] | None

Request human review (BLOCKING).

Args:
options: Dict with:
  • message: str - Review prompt

  • artifact: Any - Thing to review

  • artifact_type: str - Type of artifact

  • options: List[str] - Available actions

  • timeout: int - Timeout in seconds

  • config_key: str - Reference to hitl: declaration

Returns:
Dict with:
  • decision: str - Selected option

  • edited_artifact: Any - Modified artifact (if edited)

  • feedback: str - Human feedback

Example (Lua):
local review = Human.review({

message = “Review this document”, artifact = document, artifact_type = “document”, options = {“approve”, “edit”, “reject”}

})

if review.decision == “approve” then

publish(review.artifact)

end