Agent Creation — Subject Creation & Deployment
Creating a running agent has three steps:
- Create a Subject — store the agent specification in the subjects service.
- Register an Agent Deployer — install the deployer into a Kubernetes cluster (once per cluster).
- Deploy the Agent — ask the deployer to run the agent's executor and instances. This creates a Runtime Subject that records where the agent is running.
All endpoints below are served by the subjects service. Every response has the shape { "success": <bool>, "data": ..., "message": "..." }.
Set a base variable (optional):
export SUBJECT_DB_URL="http://<subjects-service-host>:<port>"
1) Create a Subject
The body is a full Agent Specification. identity.subject_version is required. Set info.container_image_name to the agent's container image — the deployer runs this image for each agent instance.
Minimal payload
curl -sS -X POST "$SUBJECT_DB_URL/api/subjects" \
-H "Content-Type: application/json" \
-d '{
"identity": {
"subject_id": "policy-researcher-1",
"subject_name": "Policy Researcher",
"subject_type": "researcher",
"subject_version": { "version": "1.0.0", "release_tag": "stable" }
},
"info": {
"container_image_name": "registry.example.org/agents/policy-researcher:latest"
},
"metadata": {
"subject_description": "Analyzes policy proposals and drafts briefs",
"subject_search_tags": ["policy","analysis"]
},
"persona": {
"role": "Policy Analyst",
"goal": "Summarize and critique policy drafts",
"persona": "Pragmatic, neutral, cites sources",
"default_system_message": "Answer with citations and balanced tone."
},
"prompting": {},
"execution": { "logging_level": "INFO" },
"integrations": {},
"runtime": { "resources": { "device": "cpu", "cpu_cores": 1.0, "memory_mb": 2048 } },
"owner": { "org_name": "ExampleOrg", "owners": ["owner@example.org"] }
}'
identity.subject_id is optional. If you omit it, the service generates one (a MongoDB ObjectId string). Creating a subject with an existing subject_id fails with HTTP 400.
Example response (HTTP 201) — the stored subject, with all defaults filled in:
{
"success": true,
"data": {
"identity": {
"subject_id": "policy-researcher-1",
"subject_name": "Policy Researcher",
"subject_type": "researcher",
"subject_version": { "version": "1.0.0", "release_tag": "stable" }
},
"info": { "container_image_name": "registry.example.org/agents/policy-researcher:latest", "...": "..." },
"metadata": { "...": "..." },
"persona": { "...": "..." },
"prompting": { "...": "..." },
"execution": { "...": "..." },
"integrations": { "...": "..." },
"runtime": { "...": "..." },
"owner": { "...": "..." }
}
}
Other Subject endpoints
| Method & Path | Description |
|---|---|
GET /api/subjects/<subject_id> |
Get a subject (404 if not found) |
PUT /api/subjects/<subject_id> |
Replace a subject with a full specification |
PATCH /api/subjects/<subject_id> |
Update fields: body { "update": { "identity.subject_name": "New Name" } } |
DELETE /api/subjects/<subject_id> |
Delete a subject |
GET /api/subjects?subject_type=<type>&tags=<a,b>&limit=50&skip=0 |
List subjects, optionally filtered by type and search tags (any match) |
POST /api/subjects/query |
Query with a MongoDB filter: body { "query": {...}, "projection": {...}, "sort": [...], "limit": 50, "skip": 0 } |
GET /api/subjects/health |
Health check |
curl -sS "$SUBJECT_DB_URL/api/subjects/policy-researcher-1"
2) Register an Agent Deployer
An agent deployer is a service running inside a Kubernetes cluster that creates agent workloads. Register one per cluster:
curl -sS -X POST "$SUBJECT_DB_URL/api/agent-deployers" \
-H "Content-Type: application/json" \
-d '{
"kubeconfig": { "...": "kubeconfig of the target cluster, as JSON" },
"deployer_id": "deployer-111",
"deployer_name": "deployer-111",
"deployer_cluster_id": "gcp-cluster-2",
"deployer_public_ip": "35.223.239.192"
}'
| Field | Required | Description |
|---|---|---|
kubeconfig |
Yes | Kubeconfig (as a JSON object) used to install the deployer into the cluster |
deployer_id |
Yes | Unique ID of the deployer |
deployer_name |
Yes | Human-readable name |
deployer_cluster_id |
Yes | ID of the cluster |
deployer_public_ip |
Yes | Not checked by the API, but needed. Public IP of a cluster node. The deployer is exposed on NodePort 30777, so its URL becomes http://<deployer_public_ip>:30777. Agent and workflow URLs are built from this IP |
The deployer is installed in the agent-deployer namespace. If saving the record fails, the installed Kubernetes resources are rolled back.
| Method & Path | Description |
|---|---|
GET /api/agent-deployers?cluster_id=<id>&limit=50&skip=0 |
List deployers |
POST /api/agent-deployers/query |
Query deployers (same body as subject queries) |
PUT / PATCH /api/agent-deployers/<deployer_id> |
Replace / update a deployer record |
DELETE /api/agent-deployers/<deployer_id> |
Uninstall the deployer (body: { "kubeconfig": {...} }) and delete its record |
3) Deploy the Agent
curl -sS -X POST "$SUBJECT_DB_URL/api/deploy-agent/deployer-111" \
-H "Content-Type: application/json" \
-d '{
"subject_id": "policy-researcher-1",
"allocation": {
"delegate_api_url": "http://35.223.239.192:30725",
"instances": [
{ "instance_id": "i1", "subject_id": "policy-researcher-1" },
{ "instance_id": "i2", "subject_id": "policy-researcher-1", "node_selector": { "pool": "cpu" } }
],
"meshes": [
{ "mesh_id": "mesh-a", "url": "nats://10.104.140.46:4222" }
]
}
}'
| Field | Required | Description |
|---|---|---|
subject_id |
Yes | Subject to deploy |
allocation.instances |
Yes | Agent instances to create. Each needs instance_id and subject_id; node_selector is optional |
allocation.meshes |
No | P2P meshes (NATS) to join, as { "mesh_id", "url" } |
allocation.delegate_api_url |
Yes* | Delegate API URL given to the agent instances (AGENT_DELEGATE_URL), used by context.delegator. *Not checked by the API, but agent instances built on the agents SDK fail to start without it |
The deployer creates the following in the agents namespace:
- Agent executor — one Deployment with the executor, a scouter and Redis, exposed through two
NodePortservices: executor port9000and scouter port10000. The executor receives tasks (/submitTask), applies the subject's policies and load-balances tasks across instances. - Agent instances — one Deployment per instance, running the image from
info.container_image_namewith a Redis sidecar. Each instance getsSUBJECT_ID,INSTANCE_ID,SUBJECT_DB_URL,MESH_LIST,AGENT_DELEGATE_URLandJOB_EXCHANGE_API_URL. It exposes ports8765(WebSocket) and9090(metrics).
On success a Runtime Subject is stored with runtime_subject_id = subject_id:
{
"success": true,
"data": {
"runtime_subject_id": "policy-researcher-1",
"subject_id": "policy-researcher-1",
"runtime_status": "active",
"runtime_info": {
"executor": "http://35.223.239.192:31412",
"scouter": "http://35.223.239.192:31413",
"deployment_data": {
"executor": { "port": 9000, "node_port": 31412, "...": "..." },
"scouter": { "port": 10000, "node_port": 31413, "...": "..." }
}
}
}
}
runtime_info.executor is the URL the Delegate API uses to send tasks to this agent. Deploying a subject that already has a runtime subject fails with HTTP 400 (the record already exists).
Remove an Agent
curl -sS -X POST "$SUBJECT_DB_URL/api/remove-agent/deployer-111/policy-researcher-1"
This removes the agent's executor and related Kubernetes resources and deletes the runtime subject.
Querying Running Agents (Runtime Subjects API)
Deployed agents are recorded as runtime subjects. Use these endpoints to find where an agent is running.
GET /api/runtime-subjects/<runtime_subject_id>
curl -sS "$SUBJECT_DB_URL/api/runtime-subjects/policy-researcher-1"
The response has the same shape as the deploy response above.
GET /api/runtime-subjects
List runtime subjects. All query parameters are optional:
| Parameter | Description |
|---|---|
subject_id |
Filter by subject ID |
runtime_status |
Filter by status (e.g. active) |
sort |
<field>:asc or <field>:desc |
limit, skip |
Paging (defaults 50, 0) |
curl -sS "$SUBJECT_DB_URL/api/runtime-subjects?runtime_status=active&limit=20"
POST /api/runtime-subjects/query
Query runtime subjects with a MongoDB-style filter. The filter goes in query:
1) Runtime subjects of one subject that are active
curl -sS -X POST "$SUBJECT_DB_URL/api/runtime-subjects/query" \
-H "Content-Type: application/json" \
-d '{
"query": { "subject_id": "policy-researcher-1", "runtime_status": "active" }
}'
2) Runtime subjects whose ID matches a prefix (case-insensitive)
curl -sS -X POST "$SUBJECT_DB_URL/api/runtime-subjects/query" \
-H "Content-Type: application/json" \
-d '{
"query": { "runtime_subject_id": { "$regex": "^policy", "$options": "i" } },
"limit": 10
}'
Other Runtime Subject endpoints
| Method & Path | Description |
|---|---|
POST /api/runtime-subjects |
Create a runtime subject: { "runtime_subject_id", "subject_id", "runtime_info", "runtime_status" } |
PUT /api/runtime-subjects/<id> |
Replace a runtime subject |
PATCH /api/runtime-subjects/<id> |
Update fields: body { "update": { ... } } |
DELETE /api/runtime-subjects/<id> |
Delete the record only (Kubernetes resources are not removed) |
GET /api/runtime-subjects/health |
Health check |