# API Contract for grix-connector Agents

## Purpose

This contract covers remote Agent and category administration through `grix_admin`, followed by local binding to grix-connector when required.

## Base Rules

1. Do not ask users for a website account or password.
2. Perform remote creation and category actions through `grix_admin` on the current account's authenticated WS channel.
3. Require a concrete `agentName` and professional `introduction` before remote creation.
4. If agent parameters are incomplete and the current account cannot create remotely, require backend admin creation first.
5. Report the exact missing scope when the service returns `code=4003`.
6. Local config writing alone is not full convergence. Verify reload, `alive=true`, and the platform connection when the current invocation can do so.

## Direct Actions

### Create Agent

```json
{
  "action": "create_agent",
  "agentName": "ops helper",
  "introduction": "Professional deployment operations Agent responsible for release readiness checks, change coordination, on-call triage, and clear status reporting; requests confirmation before high-risk operations.",
  "isMain": false,
  "categoryName": "Project Assistant",
  "parentCategoryId": "0",
  "categorySortOrder": 10
}
```

Read `createdAgent.id`, `createdAgent.agent_name`, `createdAgent.api_endpoint`, and `createdAgent.api_key` from the result. Required scope is `agent.api.create`, plus category scopes when category fields are supplied.

### Category Actions

```json
{ "action": "list_categories" }
```

```json
{
  "action": "create_category",
  "name": "Project Assistant",
  "parentId": "0",
  "sortOrder": 10
}
```

```json
{
  "action": "update_category",
  "categoryId": "20001",
  "name": "On-call Assistant",
  "parentId": "0",
  "sortOrder": 20
}
```

```json
{
  "action": "assign_category",
  "agentId": "10001",
  "categoryId": "20001"
}
```

Use `categoryId: "0"` to clear an assignment. Required scopes are `agent.category.list`, `agent.category.create`, `agent.category.update`, and `agent.category.assign` respectively.

## Local Binding

Manage `~/.grix/config/agents.json` directly:

1. Initialize a missing file as `{ "agents": [] }`.
2. Match the existing entry by `name === agent_name`; update it or append a new entry.
3. Map fields as follows:

| Input | Config field |
| --- | --- |
| `agent_name` | `name` |
| `api_endpoint` | `ws_url` |
| `agent_id` | `agent_id` |
| `api_key` | `api_key` |
| `client_type` | `client_type` |

4. Before writing, create `~/.grix/config/agents.json.bak.<YYYYMMDDHHMMSS>`.
5. Preserve valid JSON and set both files to `0o600`.
6. If the daemon is running, call synchronous `POST http://127.0.0.1:<admin-port>/api/reload`. Resolve a customized port from `~/.grix/data/admin-port`.
7. Verify through `GET http://127.0.0.1:<admin-port>/api/agents` that the entry exists and has `alive=true`.
8. Verify the platform connection through the latest daemon log or a test message. `alive=true` alone does not prove authentication succeeded.

## `connector-bind-local`

Example request (plain text from the owner or platform; `grix_admin` itself has no `task` parameter):

```text
connector-bind-local
agent_name=programmer-pi
agent_id=2079349263263338496
api_endpoint=wss://grix.dhf.pub/v1/agent-api/ws?agent_id=2079349263263338496
api_key=ak_xxx
client_type=pi
```

This mode performs local binding only. Stop on config, reload, or verification failure and report the exact failed phase.

## `create-and-connector-bind`

```text
create-and-connector-bind
agentName=Programmer Pi
introduction=Software engineering agent: analyzes requirements, designs and implements changes, writes and verifies code; asks for confirmation before destructive operations or when scope is unclear.
isMain=false
clientType=pi
categoryName=Developers
parentCategoryId=0
categorySortOrder=10
```

Execution order:

1. Validate `agentName`, `introduction`, and category-field exclusivity.
2. Call `action=create_agent` once with all supplied creation and category fields.
3. Supplement category resolution only if the response did not complete it.
4. Read the returned agent parameters.
5. Continue with `connector-bind-local`, using `clientType` or the default `pi`.
6. Complete reload, `alive=true`, and platform-connection verification before claiming full convergence.

## `category-manage`

```text
category-manage
operation=assign
agentId=10001
categoryId=0
```

Map `list`, `create`, `update`, and `assign` to their corresponding direct actions. Never execute across accounts or fall back to handwritten HTTP.
