Skip to content

Agent Protocol Reference

Foreman communicates with agents using a simple JSON-over-HTTP protocol. The harness sends a TaskMessage to the agent's /task endpoint and receives a DecisionMessage in response.

The harness executes all GitHub API calls. Agents never call GitHub directly — they only produce a decision and an ordered list of actions.

Endpoints

Agents must expose these two HTTP endpoints:

Method Path Description
POST /task Receive a task and return a decision
GET /health Health check; must return 200 OK

TaskMessage

Sent from the harness to an agent container via POST /task.

Schema

Field Type Description
task_id string (UUID4) Unique identifier for this task. Generated by the harness.
type string Task type. Currently always "issue.triage".
repo string Repository in owner/repo format.
payload object Raw GitHub event payload for the issue.
context TaskContext Harness-injected context.

TaskContext

Field Type Description
llm_backend LLMBackendRef LLM backend the agent should use for this task.
memory_summary string or null LLM-generated summary of prior actions on this issue. null if no prior actions exist.

LLMBackendRef

Field Type Description
provider string LLM provider identifier (e.g. "anthropic", "ollama").
model string Model name or identifier (e.g. "claude-sonnet-4-6").

Example

{
  "task_id": "a3f8c2d1-4b5e-4f6a-8c9d-0e1f2a3b4c5d",
  "type": "issue.triage",
  "repo": "callowayproject/bump-my-version",
  "payload": {
    "action": "opened",
    "issue": {
      "number": 42,
      "title": "Crash when version file is missing",
      "body": "Running bump-my-version fails with a KeyError when ...",
      "labels": [],
      "state": "open"
    }
  },
  "context": {
    "llm_backend": {
      "provider": "anthropic",
      "model": "claude-sonnet-4-6"
    },
    "memory_summary": "Issue #42 previously labelled 'bug' on 2026-04-10. No further actions."
  }
}

DecisionMessage

Returned by the agent in response to a POST /task request.

Schema

Field Type Description
task_id string Must match the task_id from the corresponding TaskMessage.
decision DecisionType The agent's decision on how to handle the task.
rationale string Human-readable explanation of the decision. Stored in the action log.
actions list of ActionItem Ordered list of actions for the harness to execute. May be empty.

DecisionType

Value Meaning
"label_and_respond" Apply labels and post a comment. Include add_label and comment actions.
"close" Close the issue. Requires a close_issue action and allow_close: true in the agent config.
"escalate" Flag the issue for human attention. No automatic actions are executed; the decision is logged.
"skip" Take no action. The decision is logged but no GitHub API calls are made.

Example

{
  "task_id": "a3f8c2d1-4b5e-4f6a-8c9d-0e1f2a3b4c5d",
  "decision": "label_and_respond",
  "rationale": "Issue describes a crash with a clear exception — classified as a bug.",
  "actions": [
    {
      "type": "add_label",
      "label": "bug"
    },
    {
      "type": "comment",
      "body": "Thanks for the report! This looks like a bug. We'll investigate."
    }
  ]
}

ActionItem

Each entry in the actions list is an ActionItem. All action items share a type field; additional fields depend on the action type.

The harness executes actions in the order they appear in the list. The decision is written to the action log before any GitHub API call is attempted.

Action Types

add_label

Adds a label to the issue. The label must already exist in the repository.

Field Type Description
type string "add_label"
label string Name of the label to add.
{
  "type": "add_label",
  "label": "bug"
}

comment

Posts a comment on the issue as the bot account.

Field Type Description
type string "comment"
body string Markdown-formatted comment body.
{
  "type": "comment",
  "body": "Thanks for the report! We'll take a look."
}

close_issue

Closes the issue. This action is silently skipped unless the agent's configuration includes allow_close: true. See agent assignment config.

Field Type Description
type string "close_issue"
{
  "type": "close_issue"
}

Error Handling

If the agent returns an unrecognized action type, the harness raises UnknownActionError and stops processing remaining actions. Actions already executed before the error are not rolled back.

If the agent's /task endpoint returns a non-2xx status or is unreachable, the harness logs the error and does not execute any actions for that event.