From 1f351a173493b6225799ae71c8ab70099fb2821c Mon Sep 17 00:00:00 2001 From: Zer4tul Date: Tue, 12 May 2026 18:34:23 +0800 Subject: [PATCH] docs: replace localhost with FLEET_API_URL, add persistence and heartbeat guidance - Replace all localhost:9090 with FLEET_API_URL:PORT placeholder - Add Step 0: persist Fleet API URL to agent memory - Clarify heartbeat must be periodic loop (60s interval) - Add execution mode self-selection decision flow - Add persisting configuration section (URL, agent_id, token) --- docs/agent-api-reference.md | 31 ++++---- docs/agent-onboarding-guide.md | 105 ++++++++++++++++++++++++--- skill/SKILL.md | 125 ++++++++++++++++++++++++++------- 3 files changed, 213 insertions(+), 48 deletions(-) diff --git a/docs/agent-api-reference.md b/docs/agent-api-reference.md index 3c07b8c..b8f7c5c 100644 --- a/docs/agent-api-reference.md +++ b/docs/agent-api-reference.md @@ -1,8 +1,11 @@ # Agent Fleet — HTTP API Reference -Base URL: `http://:9090` +`FLEET_API_URL:PORT` means the address of your Agent Fleet Orchestrator (for example, `100.102.101.43:9090`). If you do not know it, ask your user for the Fleet API address before using these examples. + +Base URL: `http://FLEET_API_URL:PORT` Content-Type: `application/json` for all request/response bodies unless noted. All timestamps are ISO 8601 (RFC 3339). +If you do not know the Fleet API URL, ask the user who deployed the orchestrator. --- @@ -56,7 +59,7 @@ GET /healthz **Response:** `200 OK` — body: `ok` ```bash -curl http://localhost:9090/healthz +curl http://FLEET_API_URL:PORT/healthz ``` --- @@ -90,7 +93,7 @@ Register a new agent or update an existing one (upsert by `agent_id`). ``` ```bash -curl -X POST http://localhost:9090/api/v1/agents/register \ +curl -X POST http://FLEET_API_URL:PORT/api/v1/agents/register \ -H 'Content-Type: application/json' \ -d '{ "agent_id": "worker-01", @@ -109,6 +112,8 @@ curl -X POST http://localhost:9090/api/v1/agents/register \ POST /api/v1/agents/heartbeat ``` +This endpoint MUST be called periodically (default: every 60s). A single call is not sufficient. Missing heartbeats will cause the agent to be marked offline and its tasks requeued. + **Request:** | Field | Type | Required | Description | @@ -128,7 +133,7 @@ POST /api/v1/agents/heartbeat **Errors:** `404` if agent not found. ```bash -curl -X POST http://localhost:9090/api/v1/agents/heartbeat \ +curl -X POST http://FLEET_API_URL:PORT/api/v1/agents/heartbeat \ -H 'Content-Type: application/json' \ -d '{"agent_id": "worker-01"}' ``` @@ -160,7 +165,7 @@ Sets agent offline and requeues all its active tasks back to `created`. ``` ```bash -curl -X POST http://localhost:9090/api/v1/agents/deregister \ +curl -X POST http://FLEET_API_URL:PORT/api/v1/agents/deregister \ -H 'Content-Type: application/json' \ -d '{"agent_id": "worker-01"}' ``` @@ -183,7 +188,7 @@ GET /api/v1/agents **Response:** `200 OK` — JSON array of [Agent](#agent-object) objects. ```bash -curl 'http://localhost:9090/api/v1/agents?status=online' +curl 'http://FLEET_API_URL:PORT/api/v1/agents?status=online' ``` --- @@ -204,7 +209,7 @@ GET /api/v1/tasks **Response:** `200 OK` — JSON array of [Task](#task-object) objects. Ordered by `created_at` descending. ```bash -curl 'http://localhost:9090/api/v1/tasks?status=running' +curl 'http://FLEET_API_URL:PORT/api/v1/tasks?status=running' ``` --- @@ -220,7 +225,7 @@ GET /api/v1/tasks/{task_id} **Errors:** `404` if task not found. ```bash -curl http://localhost:9090/api/v1/tasks/org%2Frepo%2342 +curl http://FLEET_API_URL:PORT/api/v1/tasks/org%2Frepo%2342 ``` --- @@ -245,7 +250,7 @@ Requires Bearer token if `http_pull_token` is configured. Only returns tasks wit **Errors:** `401` if token required and missing/invalid. ```bash -curl -X POST http://localhost:9090/api/v1/tasks/dequeue \ +curl -X POST http://FLEET_API_URL:PORT/api/v1/tasks/dequeue \ -H 'Content-Type: application/json' \ -H 'Authorization: Bearer my-token' \ -d '{"agent_id": "worker-03", "capabilities": ["code:rust"]}' @@ -272,7 +277,7 @@ Requires Bearer token. Only works for tasks with `execution_mode = http_pull`. **Errors:** `400` if task is not `http_pull` mode or transition is invalid. `404` if task not found. ```bash -curl -X POST http://localhost:9090/api/v1/tasks/org%2Frepo%2342/status \ +curl -X POST http://FLEET_API_URL:PORT/api/v1/tasks/org%2Frepo%2342/status \ -H 'Content-Type: application/json' \ -H 'Authorization: Bearer my-token' \ -d '{"status": "running"}' @@ -302,7 +307,7 @@ Works for both `ssh_cli` and `http_pull` tasks. Submit a receipt to mark the tas **Errors:** `404` if task not found. `400` if task is not in a completable state. ```bash -curl -X POST http://localhost:9090/api/v1/tasks/org%2Frepo%2342/complete \ +curl -X POST http://FLEET_API_URL:PORT/api/v1/tasks/org%2Frepo%2342/complete \ -H 'Content-Type: application/json' \ -d '{ "task_id": "org/repo#42", @@ -332,7 +337,7 @@ Retry a `failed` or `agent_lost` task. Transitions it back to `assigned`. **Errors:** `400` if task status is not `failed` or `agent_lost`. `404` if task not found. ```bash -curl -X POST http://localhost:9090/api/v1/tasks/org%2Frepo%2342/retry +curl -X POST http://FLEET_API_URL:PORT/api/v1/tasks/org%2Frepo%2342/retry ``` --- @@ -352,7 +357,7 @@ Submit a receipt for a task. Validates artifacts (e.g. checks PR exists via Forg **Errors:** `404` if task not found. `400` if validation fails. ```bash -curl -X POST http://localhost:9090/api/v1/receipts \ +curl -X POST http://FLEET_API_URL:PORT/api/v1/receipts \ -H 'Content-Type: application/json' \ -d '{ "task_id": "org/repo#42", diff --git a/docs/agent-onboarding-guide.md b/docs/agent-onboarding-guide.md index e9e99ec..d55b5a0 100644 --- a/docs/agent-onboarding-guide.md +++ b/docs/agent-onboarding-guide.md @@ -1,5 +1,7 @@ # Agent Fleet — Agent Onboarding Guide +`FLEET_API_URL:PORT` means the address of your Agent Fleet Orchestrator (for example, `100.102.101.43:9090`). If you do not know it, ask your user for the Fleet API address before using these examples. + This guide explains how to integrate an agent with the Agent Fleet Orchestrator. --- @@ -19,6 +21,81 @@ Agent Fleet supports two execution modes. The mode is set per-task at creation t --- +## How to Choose an Execution Mode + +Start by asking: **"What is the address of the Agent Fleet Orchestrator?"** +If you do not know the address, ask your user. + +Then decide based on connectivity and control model: + +1. **Use `ssh_cli`** if: + - You have a CLI binary that can run non-interactively + - The Fleet orchestrator can SSH into your machine or server + - You want the Orchestrator to initiate execution for each task + +2. **Use `http_pull`** if: + - The Fleet orchestrator cannot SSH into your machine + - You are behind NAT, a firewall, or on a network the Orchestrator cannot reach + - You already have your own scheduler, worker loop, or bot runtime + - You want your agent to decide when to pull work + +3. **If unsure**, ask your user: + - **"Can the Fleet orchestrator SSH into this machine?"** + - If yes → `ssh_cli` + - If no → `http_pull` + +--- + +### Self-Determination Decision Flow + +As an agent, you can self-determine your mode by answering these questions: + +``` +1. Do I have a CLI binary that can execute tasks non-interactively? + └─ NO → Use http_pull + └─ YES → Continue + +2. Can the Fleet orchestrator SSH into my machine? + └─ NO → Use http_pull + └─ YES → Continue + +3. Do I have my own scheduler, worker loop, or bot runtime? + └─ YES → Use http_pull (you prefer to control your own task flow) + └─ NO → Continue + +4. Do I want the Orchestrator to initiate execution remotely? + └─ YES → Use ssh_cli + └─ NO → Use http_pull +``` + +**Quick reference:** If you can be reached via SSH and don't have a custom scheduler, use `ssh_cli`. Otherwise, use `http_pull`. + +### Decision Table + +| Question | If Yes | If No | +|----------|--------|-------| +| Do you have a CLI binary that can execute tasks non-interactively? | Continue evaluating for `ssh_cli` | Use `http_pull` | +| Can the Fleet orchestrator SSH into this machine? | Use `ssh_cli` | Use `http_pull` | +| Is this agent behind NAT, a firewall, or otherwise unreachable from the Orchestrator? | Use `http_pull` | Continue evaluating | +| Does the agent already run its own scheduler or task loop? | Use `http_pull` | Either mode may fit | +| Do you want the Orchestrator to launch the agent process remotely? | Use `ssh_cli` | Use `http_pull` | + +### Common Scenarios + +| Scenario | Recommended Mode | Why | +|----------|------------------|-----| +| Codex / Claude Code / OpenCode on a reachable server | `ssh_cli` | Fleet can SSH in and run the CLI directly | +| OpenClaw / Hermes Agent / bot framework | `http_pull` | The agent already has a runtime and should pull work itself | +| Agent running on a laptop behind NAT | `http_pull` | Fleet cannot reach it reliably over SSH | +| Shared VM with a well-known SSH host and installed CLI | `ssh_cli` | Centralized orchestration is simpler | + +### Simple Rule of Thumb + +- If the Fleet server can **reach you**, `ssh_cli` is usually simpler. +- If you must **reach the Fleet server**, use `http_pull`. + +--- + ## ssh_cli Workflow ### 1. Configure a Host @@ -107,19 +184,29 @@ If output is not valid JSON, the task is marked `failed`. ### 1. Register ```bash -curl -X POST http://localhost:9090/api/v1/agents/register \ +curl -X POST http://FLEET_API_URL:PORT/api/v1/agents/register \ -H 'Content-Type: application/json' \ -d '{"agent_id": "worker-03", "agent_type": "openclaw", "hostname": "arm0", "capabilities": ["code:rust"], "max_concurrency": 2}' ``` Response contains a `registry_token`. Keep it for subsequent API calls (if `http_pull_token` is configured, use that shared token instead). +Recommended immediately after registration: +- Persist `FLEET_API_URL`, your `agent_id`, and the returned `registry_token` +- Start the heartbeat loop before your first dequeue request + ### 2. Heartbeat (periodic) -Send a heartbeat every N seconds (default interval: 60s). If the Orchestrator doesn't receive one within `heartbeat_interval_secs × heartbeat_timeout_threshold`, the agent is marked offline and its tasks are requeued. +Heartbeat must be a background loop, not a one-shot call. + +- Default heartbeat interval: every 60 seconds +- Recommended behavior: start the loop immediately after registration, before the first dequeue +- If the Orchestrator does not receive a heartbeat within `heartbeat_interval_secs × heartbeat_timeout_threshold` (default: 180 seconds), the agent is marked offline +- When an agent is marked offline, its assigned tasks are requeued +- The heartbeat loop should run for the entire lifetime of the agent ```bash -curl -X POST http://localhost:9090/api/v1/agents/heartbeat \ +curl -X POST http://FLEET_API_URL:PORT/api/v1/agents/heartbeat \ -H 'Content-Type: application/json' \ -d '{"agent_id": "worker-03"}' ``` @@ -127,7 +214,7 @@ curl -X POST http://localhost:9090/api/v1/agents/heartbeat \ ### 3. Dequeue a Task ```bash -curl -X POST http://localhost:9090/api/v1/tasks/dequeue \ +curl -X POST http://FLEET_API_URL:PORT/api/v1/tasks/dequeue \ -H 'Content-Type: application/json' \ -H 'Authorization: Bearer ' \ -d '{"agent_id": "worker-03", "capabilities": ["code:rust"]}' @@ -140,7 +227,7 @@ Only tasks with `execution_mode = http_pull` are returned. ### 4. Update Status While Working ```bash -curl -X POST http://localhost:9090/api/v1/tasks/org%2Frepo%2342/status \ +curl -X POST http://FLEET_API_URL:PORT/api/v1/tasks/org%2Frepo%2342/status \ -H 'Content-Type: application/json' \ -H 'Authorization: Bearer ' \ -d '{"status": "running"}' @@ -149,7 +236,7 @@ curl -X POST http://localhost:9090/api/v1/tasks/org%2Frepo%2342/status \ ### 5. Complete the Task ```bash -curl -X POST http://localhost:9090/api/v1/tasks/org%2Frepo%2342/complete \ +curl -X POST http://FLEET_API_URL:PORT/api/v1/tasks/org%2Frepo%2342/complete \ -H 'Content-Type: application/json' \ -d '{ "task_id": "org/repo#42", @@ -165,7 +252,7 @@ curl -X POST http://localhost:9090/api/v1/tasks/org%2Frepo%2342/complete \ Or use the receipts endpoint: ```bash -curl -X POST http://localhost:9090/api/v1/receipts \ +curl -X POST http://FLEET_API_URL:PORT/api/v1/receipts \ -H 'Content-Type: application/json' \ -d '' ``` @@ -173,7 +260,7 @@ curl -X POST http://localhost:9090/api/v1/receipts \ ### 6. Deregister When Done ```bash -curl -X POST http://localhost:9090/api/v1/agents/deregister \ +curl -X POST http://FLEET_API_URL:PORT/api/v1/agents/deregister \ -H 'Content-Type: application/json' \ -d '{"agent_id": "worker-03"}' ``` @@ -248,7 +335,7 @@ The prompt is injected into the CLI template as the `{prompt}` variable. Other a ## FAQ **Q: How do I know which execution mode to use?** -A: If you have a CLI binary and run on a configured host → `ssh_cli`. If you have your own scheduler or run outside configured hosts → `http_pull`. +A: First determine the Fleet API address, then ask whether the Orchestrator can SSH into the machine. If it can, `ssh_cli` is usually the best fit. If it cannot, use `http_pull`. **Q: Do I need to register for ssh_cli mode?** A: No. The Orchestrator manages ssh_cli tasks entirely. Registration is only for `http_pull` agents. diff --git a/skill/SKILL.md b/skill/SKILL.md index fe57564..a3fe842 100644 --- a/skill/SKILL.md +++ b/skill/SKILL.md @@ -14,18 +14,27 @@ description: | # Agent Fleet Integration Skill +`FLEET_API_URL:PORT` means the address of your Agent Fleet Orchestrator (for example, `100.102.101.43:9090`). If you do not know it, ask your user for the Fleet API address before using these examples. + ## Quick Start (http_pull mode) +**Step 0.** Get the Fleet API URL from your user and **save it to your persistent memory**: +- Ask: "What is the Agent Fleet Orchestrator URL?" +- Example answer: `http://100.102.101.43:9090` +- **IMPORTANT**: Write this URL to your persistent storage (memory file, config, etc.) so you remember it across sessions. If you lose this URL, you cannot reconnect to the fleet. + **Step 1.** Register your agent: ```bash -curl -X POST http://localhost:9090/api/v1/agents/register \ +curl -X POST http://FLEET_API_URL:PORT/api/v1/agents/register \ -H 'Content-Type: application/json' \ -d '{"agent_id":"my-agent","agent_type":"openclaw","hostname":"myhost","capabilities":["code:rust"],"max_concurrency":2}' ``` +After registration, save your `agent_id` and `registry_token` to persistent memory too, then start a heartbeat loop immediately. The heartbeat must run for the entire lifetime of the agent. + **Step 2.** Pull and execute a task: ```bash -curl -X POST http://localhost:9090/api/v1/tasks/dequeue \ +curl -X POST http://FLEET_API_URL:PORT/api/v1/tasks/dequeue \ -H 'Content-Type: application/json' \ -H 'Authorization: Bearer ' \ -d '{"agent_id":"my-agent","capabilities":["code:rust"]}' @@ -33,7 +42,7 @@ curl -X POST http://localhost:9090/api/v1/tasks/dequeue \ **Step 3.** Submit your result: ```bash -curl -X POST http://localhost:9090/api/v1/tasks//complete \ +curl -X POST http://FLEET_API_URL:PORT/api/v1/tasks//complete \ -H 'Content-Type: application/json' \ -d '{"task_id":"","agent_id":"my-agent","status":"completed","duration_seconds":60,"summary":"done","artifacts":[],"error":null}' ``` @@ -42,30 +51,82 @@ curl -X POST http://localhost:9090/api/v1/tasks//complete \ ## Choosing Your Execution Mode -| If you... | Use this mode | -|-----------|---------------| -| Have a CLI binary installed on a configured host | `ssh_cli` — Orchestrator calls you | -| Have your own scheduler or run outside configured hosts | `http_pull` — You call the API | +Ask your user: **"What is the address of the Agent Fleet Orchestrator?"** +If you do not know the address, ask your user. + +Then determine your mode: + +1. If you have a CLI binary **and** the Fleet orchestrator can SSH into your machine: + → Use `ssh_cli` (Orchestrator calls you via SSH) + +2. If the Fleet orchestrator cannot reach your machine via SSH (for example, you are behind NAT, a firewall, or on a different network): + → Use `http_pull` (you call the Fleet API) + +3. If you have your own scheduler or task loop (for example, OpenClaw or Hermes Agent): + → Use `http_pull` (you control when to pull tasks) + +4. If unsure, try this test: + - Ask your user: **"Can the Fleet orchestrator SSH into this machine?"** + - If yes → `ssh_cli` + - If no → `http_pull` + +Common scenarios: +- Codex / Claude Code / OpenCode on a server → `ssh_cli` (Fleet SSHs in and runs your CLI) +- OpenClaw / Hermes Agent / any bot framework → `http_pull` (you pull tasks via HTTP API) +- Agent on a laptop behind NAT → `http_pull` (Fleet cannot reach you) - `ssh_cli` agents do **not** need to call any API. The Orchestrator handles everything via SSH or local subprocess. - `http_pull` agents must **register, heartbeat, dequeue, and complete** via HTTP API. --- +### Self-Determination Decision Flow + +As an agent, you can self-determine your mode by answering these questions: + +``` +1. Do I have a CLI binary that can execute tasks non-interactively? + └─ NO → Use http_pull + └─ YES → Continue + +2. Can the Fleet orchestrator SSH into my machine? + └─ NO → Use http_pull + └─ YES → Continue + +3. Do I have my own scheduler, worker loop, or bot runtime? + └─ YES → Use http_pull (you prefer to control your own task flow) + └─ NO → Continue + +4. Do I want the Orchestrator to initiate execution remotely? + └─ YES → Use ssh_cli + └─ NO → Use http_pull +``` + +**Quick reference:** If you can be reached via SSH and don't have a custom scheduler, use `ssh_cli`. Otherwise, use `http_pull`. + +--- + ## Instructions ### http_pull Agent Lifecycle ``` -Register → Heartbeat (loop) → Dequeue → Execute → Complete/Deregister +Register → Save credentials to memory → Start heartbeat loop (every 60s, runs forever) + → Dequeue (poll when idle) → Execute → Complete → Dequeue again + → On shutdown: Deregister ``` 1. **Register** once at startup via `POST /api/v1/agents/register`. -2. **Heartbeat** periodically (every 60s recommended) via `POST /api/v1/agents/heartbeat`. Without heartbeats, you will be marked offline and your tasks requeued. -3. **Dequeue** when ready for work via `POST /api/v1/tasks/dequeue`. Returns a Task or 204 No Content. -4. **Update status** to `running` via `POST /api/v1/tasks/{task_id}/status`. -5. **Complete** the task via `POST /api/v1/tasks/{task_id}/complete` with a Receipt. -6. **Deregister** when shutting down via `POST /api/v1/agents/deregister`. +2. **Save credentials to memory** immediately after registration: persist `FLEET_API_URL`, your `agent_id`, and your `registry_token` in long-term memory or a config file. +3. **Start a periodic heartbeat loop** via `POST /api/v1/agents/heartbeat`. + - Default interval: every 60 seconds + - Maximum allowed gap: `heartbeat_interval_secs × heartbeat_timeout_threshold` (default: 180 seconds) + - If you exceed that gap, you will be marked offline and your tasks will be requeued + - This must run for the entire lifetime of the agent, not just once +4. **Dequeue** when ready for work via `POST /api/v1/tasks/dequeue`. Returns a Task or 204 No Content. +5. **Update status** to `running` via `POST /api/v1/tasks/{task_id}/status`. +6. **Complete** the task via `POST /api/v1/tasks/{task_id}/complete` with a Receipt. +7. **Deregister** when shutting down via `POST /api/v1/agents/deregister`. ### ssh_cli Agent Notes @@ -81,7 +142,7 @@ No API interaction required. Ensure: ### Register ```bash -curl -X POST http://localhost:9090/api/v1/agents/register \ +curl -X POST http://FLEET_API_URL:PORT/api/v1/agents/register \ -H 'Content-Type: application/json' \ -d '{ "agent_id": "worker-03", @@ -96,7 +157,9 @@ curl -X POST http://localhost:9090/api/v1/agents/register \ ### Heartbeat ```bash -curl -X POST http://localhost:9090/api/v1/agents/heartbeat \ +# Heartbeat must be sent periodically. Example using a shell loop: +# while true; do curl -X POST http://FLEET_API_URL:PORT/api/v1/agents/heartbeat -H 'Content-Type: application/json' -d '{"agent_id": "worker-03"}'; sleep 60; done +curl -X POST http://FLEET_API_URL:PORT/api/v1/agents/heartbeat \ -H 'Content-Type: application/json' \ -d '{"agent_id": "worker-03"}' ``` @@ -104,13 +167,13 @@ curl -X POST http://localhost:9090/api/v1/agents/heartbeat \ ### List Available Tasks ```bash -curl 'http://localhost:9090/api/v1/tasks?status=created' +curl 'http://FLEET_API_URL:PORT/api/v1/tasks?status=created' ``` ### Dequeue ```bash -curl -X POST http://localhost:9090/api/v1/tasks/dequeue \ +curl -X POST http://FLEET_API_URL:PORT/api/v1/tasks/dequeue \ -H 'Content-Type: application/json' \ -H 'Authorization: Bearer my-token' \ -d '{"agent_id": "worker-03", "capabilities": ["code:rust"]}' @@ -121,13 +184,13 @@ Returns 200 with Task JSON, or 204 if no matching task. ### Get Task Detail ```bash -curl 'http://localhost:9090/api/v1/tasks/org%2Frepo%2342' +curl 'http://FLEET_API_URL:PORT/api/v1/tasks/org%2Frepo%2342' ``` ### Update Task Status ```bash -curl -X POST http://localhost:9090/api/v1/tasks/org%2Frepo%2342/status \ +curl -X POST http://FLEET_API_URL:PORT/api/v1/tasks/org%2Frepo%2342/status \ -H 'Content-Type: application/json' \ -H 'Authorization: Bearer my-token' \ -d '{"status": "running"}' @@ -136,7 +199,7 @@ curl -X POST http://localhost:9090/api/v1/tasks/org%2Frepo%2342/status \ ### Complete Task with Receipt ```bash -curl -X POST http://localhost:9090/api/v1/tasks/org%2Frepo%2342/complete \ +curl -X POST http://FLEET_API_URL:PORT/api/v1/tasks/org%2Frepo%2342/complete \ -H 'Content-Type: application/json' \ -d '{ "task_id": "org/repo#42", @@ -154,7 +217,7 @@ curl -X POST http://localhost:9090/api/v1/tasks/org%2Frepo%2342/complete \ ### Submit Receipt ```bash -curl -X POST http://localhost:9090/api/v1/receipts \ +curl -X POST http://FLEET_API_URL:PORT/api/v1/receipts \ -H 'Content-Type: application/json' \ -d '{ "task_id": "org/repo#42", @@ -170,7 +233,7 @@ curl -X POST http://localhost:9090/api/v1/receipts \ ### Retry a Failed Task ```bash -curl -X POST http://localhost:9090/api/v1/tasks/org%2Frepo%2342/retry +curl -X POST http://FLEET_API_URL:PORT/api/v1/tasks/org%2Frepo%2342/retry ``` Only works for tasks in `failed` or `agent_lost` status. @@ -178,13 +241,13 @@ Only works for tasks in `failed` or `agent_lost` status. ### List Agents ```bash -curl 'http://localhost:9090/api/v1/agents?status=online&capability=code:rust' +curl 'http://FLEET_API_URL:PORT/api/v1/agents?status=online&capability=code:rust' ``` ### Deregister ```bash -curl -X POST http://localhost:9090/api/v1/agents/deregister \ +curl -X POST http://FLEET_API_URL:PORT/api/v1/agents/deregister \ -H 'Content-Type: application/json' \ -d '{"agent_id": "worker-03"}' ``` @@ -192,7 +255,7 @@ curl -X POST http://localhost:9090/api/v1/agents/deregister \ ### Health Check ```bash -curl http://localhost:9090/healthz +curl http://FLEET_API_URL:PORT/healthz ``` --- @@ -237,10 +300,20 @@ created → assigned → running → review_pending → completed ### Heartbeat Requirements -- Send heartbeats at least every `heartbeat_interval_secs` (default: 60s). +- Send heartbeats in a background loop at least every `heartbeat_interval_secs` (default: 60s). +- A one-time heartbeat is not enough; the loop must run for the full lifetime of the agent. - If the Orchestrator doesn't receive a heartbeat within `heartbeat_interval_secs × heartbeat_timeout_threshold` (default: 60 × 3 = 180s), your agent is marked offline. - All active tasks assigned to an offline agent are requeued to `created` status. +### Persisting Configuration + +After registration, you MUST persist these values to your long-term memory or config file: +1. **FLEET_API_URL** — the orchestrator address +2. **Your agent_id** — your registered agent ID +3. **Your registry_token** — the token returned by registration (needed for http_pull auth) + +Without these, you cannot reconnect after a session restart. + --- ## Forgejo Workflow