# Agents

An agent calls tools in a loop until the task is done or it reaches its step limit. The tools are Harakumo's own actions (list projects, read usage, query vectors … and, when allowed, deploy, create or delete). They run with a temporary developer key made for the run and revoked afterwards.

Agents are for acting on your own Harakumo resources today. A run starts when you ask for one (the API, the SDK, the dashboard or an AI assistant); there is no schedule or webhook trigger yet. Custom HTTP tools, memory attached to an agent and background runs with a callback are not available yet.

## Create and run

**SDK**

```js
const { agent } = await hk.agents.create(project.id, {
  name: 'ops', model: 'claude-sonnet-5',
  instructions: 'Report failed deploys and projects close to their plan limits.',
  tools: ['list_projects', 'get_usage', 'list_deployments'],
  maxSteps: 8,
});
const { run } = await hk.agents.run(agent.id, 'What needs attention today?');
// run.status, run.output, run.steps, run.cost_micros, run.model, run.stop_reason
```

## What a run returns

`POST /api/agents/:id` answers 202 with `{ run }` once the run has finished, and `hk.agents.run` resolves with it.

| Field | Meaning |
| --- | --- |
| status | `completed` or `failed` (`running` while it is still going). |
| stop_reason | Empty when it completed. `step_limit`: it reached maxSteps without finishing. `credits`: the AI credit ran out. `spend_limit`: the monthly spending limit was reached. `error`: the model or the run failed. `stale`: the process running it stopped. |
| output | The answer or, for a run that stopped, why it stopped and what to do. |
| steps | Every step in order: `step`, `kind` (`tool` or `text`), `tool_name`, `arguments`, `result` (its first 4,000 characters) and `ok`. |
| tokens_used, cost_micros, cost_usd | What its steps used and were charged, whether it finished, stopped or failed. |
| model, duration_ms | The model that ran it, and how long it took. |

## See what a run did

Dashboard → Agents → an agent lists its recent runs. Open one to see its input, its output or why it stopped, the model, the tokens and the cost, and every step: the tool it called, the arguments it passed and what came back, with failed tool calls marked. `GET /api/agents/:id` (`hk.agents.get`) returns the same for the 20 most recent runs.

## Settings

| Field | Meaning |
| --- | --- |
| model | A tool-capable model (Claude, GPT, Grok, Kimi) or `auto` (runs on claude-sonnet-5). On Hobby, vendor models need the workspace owner's verified email. |
| tools | Tool names from `GET /api/agents/tools` (add `?writes=1` to see the ones that change things); a name that is not a tool is refused with 400. Left empty, the agent gets every tool it is allowed. Tools that manage API keys, switch workspace, run agents or need an admin (members, the audit log, the Balance, service settings) are never given to an agent. |
| allowWrites | false by default: only read tools. true lets the agent use tools that change things — deploy, create, delete, send mail, spend the Balance on domains. Turn it on deliberately. |
| maxSteps | 1–24, default 8. A run that hits it stops as failed with stop_reason step_limit. |
| instructions | Up to 16,000 characters. |

## Limits and cost

- Before a run starts, Harakumo sets aside an estimate of a few steps. With no AI credit left, or no room under the monthly spending limit, the run is refused with 402 (the same codes as an AI Gateway call) and never starts; nothing is charged.
- Each step is charged as it happens at the model's price, from included AI credit and then the Balance. A run stops as failed when the money runs out (stop_reason `credits`) or the monthly spending limit is reached (`spend_limit`); its output says which, and where on the Billing page to add funds or raise the limit.
- A run's `tokens_used` and `cost_micros` are what its steps used and were charged, whether it finished, stopped or failed.
- Runs: 6 a minute per workspace (429 `rate_limited` past it); 1 at once on hobby, 5 at once on pro, 20 at once on enterprise (429 `plan_limit` with `limit` and `current`). Input up to 32,000 characters.
- A run finishes inside the HTTP request; a run still marked running after 60 minutes is marked failed (stale).
- A paused agent answers 409 until it is resumed.
- Edit an agent with `PATCH /api/agents/:id` (model, instructions, tools, maxSteps, allowWrites); its run history is kept.
- Billing → Balance breaks this month's AI spend down by model; agent runs are one Unattributed row there for now, and each run shows its own model and cost.

## Reference

**SDK**

```js
const { agent } = await hk.agents.create(project.id, { name: 'triage', model: 'auto', tools: ['list_projects'] });
const { run } = await hk.agents.run(agent.id, 'List my projects and which are live.');
console.log(run.status, run.stop_reason, run.cost_usd, run.steps.length);
const { agent: a, runs } = await hk.agents.get(agent.id);   // the 20 most recent runs with their steps
await hk.agents.update(agent.id, { maxSteps: 12 });          // run history is kept
await hk.agents.pause(agent.id);                             // hk.agents.resume(agent.id) to run again
```

**REST**

```http
GET    /api/agents/tools?writes=1
POST   /api/projects/:id/agents   { "name", "model", "instructions"?, "tools"?: [], "maxSteps"?, "allowWrites"? }
POST   /api/agents/:id            { "input": "…" }      # run; 202 { run } once it has finished, with its steps
GET    /api/agents/:id            # the agent and its recent runs
PATCH  /api/agents/:id            { "model"?, "instructions"?, "tools"?, "maxSteps"?, "allowWrites"? } | { "action": "pause"|"resume" }
DELETE /api/agents/:id
```
