docs/sgai-skills/human-interaction/SKILL.md
Handle agent questions and work gates in sgai workspaces. Use when an agent is blocked waiting for human input, when you need to respond to multi-choice questions, approve work gates, or provide free-text answers to agent queries.
npx skillsauth add sandgardenhq/sgai human-interactionInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
When sgai agents need human input, they set needsInput: true and populate pendingQuestion in the workspace state. Your harness must detect and respond to these to unblock the agent.
Poll /api/v1/state and check each workspace:
STATE=$(curl -s $BASE_URL/api/v1/state)
# Check all workspaces for pending questions
echo $STATE | jq '.workspaces[] | select(.needsInput == true) | {name, pendingQuestion}'
A workspace with a pending question looks like:
{
"name": "my-project",
"needsInput": true,
"pendingQuestion": {
"questionId": "abc123def456ef78",
"type": "free-text",
"agentName": "coordinator",
"message": "Which database should we use for the project?",
"questions": []
}
}
free-textAgent asks an open-ended question. Respond with answer.
{
"pendingQuestion": {
"questionId": "abc123def456ef78",
"type": "free-text",
"agentName": "coordinator",
"message": "What is the primary use case for this application?",
"questions": []
}
}
Response:
curl -X POST $BASE_URL/api/v1/workspaces/my-project/respond \
-H "Content-Type: application/json" \
-d '{
"questionId": "abc123def456ef78",
"answer": "This is a B2B SaaS platform for small businesses"
}'
multi-choiceAgent presents structured questions with predefined choices.
{
"pendingQuestion": {
"questionId": "def456abc789ab12",
"type": "multi-choice",
"agentName": "coordinator",
"message": "Please answer the following questions:",
"questions": [
{
"question": "Which backend language?",
"choices": ["Go", "Python", "Node.js", "Rust"],
"multiSelect": false
},
{
"question": "Which features are required?",
"choices": ["Auth", "Payments", "Analytics", "Notifications"],
"multiSelect": true
}
]
}
}
Response (single select one choice, multi-select multiple):
curl -X POST $BASE_URL/api/v1/workspaces/my-project/respond \
-H "Content-Type: application/json" \
-d '{
"questionId": "def456abc789ab12",
"selectedChoices": ["Go", "Auth", "Analytics"],
"answer": "Also add OAuth2 integration"
}'
work-gateA decision point requiring explicit approval to proceed. The agent stops until approved.
{
"pendingQuestion": {
"questionId": "ghi789xyz123cd45",
"type": "work-gate",
"agentName": "coordinator",
"message": "Ready to begin implementation. Please review the plan and approve.",
"questions": [
{
"question": "Review complete?",
"choices": ["Approve and proceed", "Request changes", "Cancel"],
"multiSelect": false
}
]
}
}
To approve (select the approval choice):
curl -X POST $BASE_URL/api/v1/workspaces/my-project/respond \
-H "Content-Type: application/json" \
-d '{
"questionId": "ghi789xyz123cd45",
"selectedChoices": ["Approve and proceed"]
}'
Endpoint: POST /api/v1/workspaces/{name}/respond
curl -X POST $BASE_URL/api/v1/workspaces/{name}/respond \
-H "Content-Type: application/json" \
-d '{
"questionId": "QUESTION_ID_FROM_STATE",
"answer": "optional free text",
"selectedChoices": ["optional", "choice", "selections"]
}'
Request fields:
| Field | Required | Description |
|-------|----------|-------------|
| questionId | Yes | Must match the current pendingQuestion.questionId |
| answer | No | Free-text answer (used for free-text and as additional context for multi-choice) |
| selectedChoices | No | Array of selected choice strings for multi-choice/work-gate |
Response:
{
"success": true,
"message": "response submitted"
}
Errors:
409 Conflict — no pending question, or question expired (stale questionId)400 Bad Request — empty response (must provide answer or choices)The questionId is a SHA256 hash of the question content. It changes when the question changes. Always:
questionId from the current state409 "question expired" error, re-fetch state and get the new ID#!/bin/bash
BASE_URL="http://127.0.0.1:PORT"
WORKSPACE="my-project"
while true; do
STATE=$(curl -s $BASE_URL/api/v1/state)
WS=$(echo $STATE | jq --arg name "$WORKSPACE" '.workspaces[] | select(.name == $name)')
NEEDS_INPUT=$(echo $WS | jq '.needsInput')
RUNNING=$(echo $WS | jq '.running')
if [ "$NEEDS_INPUT" = "true" ]; then
QUESTION_ID=$(echo $WS | jq -r '.pendingQuestion.questionId')
TYPE=$(echo $WS | jq -r '.pendingQuestion.type')
MESSAGE=$(echo $WS | jq -r '.pendingQuestion.message')
echo "Question ($TYPE): $MESSAGE"
# Your harness logic to determine the answer...
ANSWER="My response to this question"
curl -X POST $BASE_URL/api/v1/workspaces/$WORKSPACE/respond \
-H "Content-Type: application/json" \
-d "{\"questionId\": \"$QUESTION_ID\", \"answer\": \"$ANSWER\"}"
fi
sleep 5
done
documentation
Start, stop, and steer agentic sessions in sgai workspaces. Use when you need to launch AI agent sessions, halt running sessions, or inject steering instructions to guide the agent mid-execution without stopping it.
development
Monitor sgai workspace status, events, progress, diffs, and workflow diagrams. Use when you need to observe what agents are doing, track progress, get the current state of all workspaces, subscribe to real-time updates via SSE, or inspect code changes.
development
Access agents, skills, and code snippets available in sgai workspaces. Use when you need to discover what agents are defined in a workspace, browse available skills, get skill instructions, find code snippets by language, or retrieve snippet content for a specific task.
development
Use the sgai compose wizard to create and manage GOAL.md files for workspaces. Supports reading compose state, updating wizard fields, saving drafts, previewing generated GOAL.md content, browsing workflow templates, and writing the final GOAL.md to the workspace.