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. |
comment¶
Posts a comment on the issue as the bot account.
| Field | Type | Description |
|---|---|---|
type |
string | "comment" |
body |
string | Markdown-formatted comment body. |
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" |
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.