mirror of
https://github.com/nearai/ironclaw.git
synced 2026-09-02 23:56:24 +08:00
349 lines
7.4 KiB
Plaintext
349 lines
7.4 KiB
Plaintext
---
|
|
title: Orchestrator API
|
|
sidebarTitle: Orchestrator
|
|
description: Internal worker API for sandbox container communication
|
|
---
|
|
|
|
The Orchestrator runs on a separate internal port (default `50051`) from the web gateway. This API is used by worker containers to communicate with the orchestrator for LLM calls, credential injection, and job lifecycle management.
|
|
|
|
<Note>
|
|
This is an internal API. Worker containers receive a per-job bearer token during initialization. All `/worker/` endpoints require authentication.
|
|
</Note>
|
|
|
|
## Base URL
|
|
|
|
```
|
|
http://localhost:50051
|
|
```
|
|
|
|
## Authentication
|
|
|
|
Workers authenticate using per-job bearer tokens issued during container initialization:
|
|
|
|
```http
|
|
Authorization: Bearer <job_token>
|
|
```
|
|
|
|
Tokens are scoped to specific job IDs and rejected if used for other jobs.
|
|
|
|
---
|
|
|
|
## Health
|
|
|
|
| Method | Endpoint | Description |
|
|
|--------|----------|-------------|
|
|
| `GET` | `/health` | Liveness check — returns `200 OK` if orchestrator is running |
|
|
|
|
### GET /health
|
|
|
|
```bash
|
|
curl -s http://localhost:50051/health
|
|
# Response: "ok"
|
|
```
|
|
|
|
---
|
|
|
|
## Job Management
|
|
|
|
| Method | Endpoint | Description |
|
|
|--------|----------|-------------|
|
|
| `GET` | `/worker/{job_id}/job` | Get job description and configuration |
|
|
| `POST` | `/worker/{job_id}/status` | Worker reports current status/iteration |
|
|
| `POST` | `/worker/{job_id}/complete` | Worker reports job completion or failure |
|
|
|
|
### GET /worker/{job_id}/job
|
|
|
|
```bash
|
|
curl -s -H "Authorization: Bearer $TOKEN" \
|
|
http://localhost:50051/worker/job_01j9abc123/job | jq .
|
|
```
|
|
|
|
**Response:**
|
|
|
|
```json
|
|
{
|
|
"title": "Job job_01j9abc123",
|
|
"description": "Analyze the codebase and summarize findings",
|
|
"project_dir": "/workspace/my-project"
|
|
}
|
|
```
|
|
|
|
### POST /worker/{job_id}/status
|
|
|
|
```bash
|
|
curl -s -X POST \
|
|
-H "Authorization: Bearer $TOKEN" \
|
|
-H "Content-Type: application/json" \
|
|
-d '{
|
|
"state": "in_progress",
|
|
"message": "Running analysis",
|
|
"iteration": 3
|
|
}' \
|
|
http://localhost:50051/worker/job_01j9abc123/status
|
|
```
|
|
|
|
**Request body:**
|
|
|
|
```json
|
|
{
|
|
"state": "string (pending|running|in_progress|completed|failed)",
|
|
"message": "string (optional status message)",
|
|
"iteration": "integer (current iteration count)"
|
|
}
|
|
```
|
|
|
|
### POST /worker/{job_id}/complete
|
|
|
|
```bash
|
|
curl -s -X POST \
|
|
-H "Authorization: Bearer $TOKEN" \
|
|
-H "Content-Type: application/json" \
|
|
-d '{
|
|
"success": true,
|
|
"message": "Analysis complete. Found 5 key files."
|
|
}' \
|
|
http://localhost:50051/worker/job_01j9abc123/complete
|
|
```
|
|
|
|
**Request body:**
|
|
|
|
```json
|
|
{
|
|
"success": "boolean (required)",
|
|
"message": "string (optional result message)"
|
|
}
|
|
```
|
|
|
|
**Response:**
|
|
|
|
```json
|
|
{
|
|
"status": "ok"
|
|
}
|
|
```
|
|
|
|
---
|
|
|
|
## LLM Proxy
|
|
|
|
| Method | Endpoint | Description |
|
|
|--------|----------|-------------|
|
|
| `POST` | `/worker/{job_id}/llm/complete` | Proxy a completion request to the LLM |
|
|
| `POST` | `/worker/{job_id}/llm/complete_with_tools` | Proxy a tool-use request to the LLM |
|
|
|
|
### POST /worker/{job_id}/llm/complete
|
|
|
|
```bash
|
|
curl -s -X POST \
|
|
-H "Authorization: Bearer $TOKEN" \
|
|
-H "Content-Type: application/json" \
|
|
-d '{
|
|
"messages": [
|
|
{"role": "user", "content": "Hello"}
|
|
],
|
|
"model": "claude-3-5-sonnet-20241022",
|
|
"max_tokens": 1024,
|
|
"temperature": 0.7
|
|
}' \
|
|
http://localhost:50051/worker/job_01j9abc123/llm/complete | jq .
|
|
```
|
|
|
|
**Request body:**
|
|
|
|
```json
|
|
{
|
|
"messages": "array (ChatMessage array)",
|
|
"model": "string (model identifier)",
|
|
"max_tokens": "integer (optional, default from config)",
|
|
"temperature": "float (optional, 0.0-1.0)",
|
|
"stop_sequences": "array (optional)"
|
|
}
|
|
```
|
|
|
|
**Response:**
|
|
|
|
```json
|
|
{
|
|
"content": "LLM response text",
|
|
"input_tokens": 15,
|
|
"output_tokens": 42,
|
|
"finish_reason": "stop"
|
|
}
|
|
```
|
|
|
|
### POST /worker/{job_id}/llm/complete_with_tools
|
|
|
|
```bash
|
|
curl -s -X POST \
|
|
-H "Authorization: Bearer $TOKEN" \
|
|
-H "Content-Type: application/json" \
|
|
-d '{
|
|
"messages": [
|
|
{"role": "user", "content": "List files in the project"}
|
|
],
|
|
"tools": [
|
|
{
|
|
"name": "shell",
|
|
"description": "Execute shell commands",
|
|
"input_schema": {
|
|
"type": "object",
|
|
"properties": {
|
|
"command": {"type": "string"}
|
|
}
|
|
}
|
|
}
|
|
],
|
|
"model": "claude-3-5-sonnet-20241022",
|
|
"max_tokens": 1024
|
|
}' \
|
|
http://localhost:50051/worker/job_01j9abc123/llm/complete_with_tools | jq .
|
|
```
|
|
|
|
**Request body:**
|
|
|
|
```json
|
|
{
|
|
"messages": "array (ChatMessage array)",
|
|
"tools": "array (Tool definition array)",
|
|
"model": "string (model identifier)",
|
|
"max_tokens": "integer",
|
|
"temperature": "float (optional)",
|
|
"tool_choice": "string (optional, 'auto'|'none'|tool name)"
|
|
}
|
|
```
|
|
|
|
**Response:**
|
|
|
|
```json
|
|
{
|
|
"content": "I'll list the files for you.",
|
|
"tool_calls": [
|
|
{
|
|
"id": "call_abc123",
|
|
"name": "shell",
|
|
"input": {"command": "ls -la"}
|
|
}
|
|
],
|
|
"input_tokens": 120,
|
|
"output_tokens": 85,
|
|
"finish_reason": "tool_use"
|
|
}
|
|
```
|
|
|
|
---
|
|
|
|
## Job Events
|
|
|
|
| Method | Endpoint | Description |
|
|
|--------|----------|-------------|
|
|
| `POST` | `/worker/{job_id}/event` | Worker sends events (message, tool_use, tool_result, result) |
|
|
|
|
### POST /worker/{job_id}/event
|
|
|
|
```bash
|
|
curl -s -X POST \
|
|
-H "Authorization: Bearer $TOKEN" \
|
|
-H "Content-Type: application/json" \
|
|
-d '{
|
|
"event_type": "message",
|
|
"data": {
|
|
"role": "assistant",
|
|
"content": "Analyzing the codebase..."
|
|
}
|
|
}' \
|
|
http://localhost:50051/worker/job_01j9abc123/event
|
|
```
|
|
|
|
**Event types:**
|
|
|
|
| Event Type | Data Fields |
|
|
|------------|-------------|
|
|
| `message` | `role`, `content` |
|
|
| `tool_use` | `tool_name`, `input` |
|
|
| `tool_result` | `tool_name`, `output` |
|
|
| `result` | `status`, `session_id` (optional) |
|
|
|
|
**Response:** `200 OK` on success
|
|
|
|
---
|
|
|
|
## Claude Code Bridge
|
|
|
|
| Method | Endpoint | Description |
|
|
|--------|----------|-------------|
|
|
| `GET` | `/worker/{job_id}/prompt` | Get next queued follow-up prompt for Claude Code |
|
|
|
|
### GET /worker/{job_id}/prompt
|
|
|
|
```bash
|
|
curl -s -H "Authorization: Bearer $TOKEN" \
|
|
http://localhost:50051/worker/job_01j9abc123/prompt
|
|
```
|
|
|
|
**Response (with pending prompt):**
|
|
|
|
```json
|
|
{
|
|
"content": "What is the current git status?",
|
|
"done": false
|
|
}
|
|
```
|
|
|
|
**Response (queue empty):** `204 No Content`
|
|
|
|
---
|
|
|
|
## Credentials
|
|
|
|
| Method | Endpoint | Description |
|
|
|--------|----------|-------------|
|
|
| `GET` | `/worker/{job_id}/credentials` | Get decrypted secrets granted to this job |
|
|
|
|
### GET /worker/{job_id}/credentials
|
|
|
|
```bash
|
|
curl -s -H "Authorization: Bearer $TOKEN" \
|
|
http://localhost:50051/worker/job_01j9abc123/credentials | jq .
|
|
```
|
|
|
|
**Response:**
|
|
|
|
```json
|
|
[
|
|
{
|
|
"env_var": "GITHUB_TOKEN",
|
|
"value": "ghp_xxxxxxxxxxxx"
|
|
},
|
|
{
|
|
"env_var": "DATABASE_URL",
|
|
"value": "postgres://user:pass@localhost/db"
|
|
}
|
|
]
|
|
```
|
|
|
|
**Response (no grants):** `204 No Content`
|
|
|
|
**Response (secrets store unavailable):** `503 Service Unavailable`
|
|
|
|
---
|
|
|
|
## Error Codes
|
|
|
|
| Status | Code | Description |
|
|
|--------|------|-------------|
|
|
| `401` | Unauthorized | Missing or invalid job token |
|
|
| `404` | Not Found | Job not found or container not running |
|
|
| `503` | Service Unavailable | Secrets store not configured |
|
|
|
|
---
|
|
|
|
## Configuration
|
|
|
|
The orchestrator port is configured via:
|
|
|
|
| Environment Variable | Default | Description |
|
|
|----------------------|---------|-------------|
|
|
| `ORCHESTRATOR_PORT` | `50051` | Internal API port |
|
|
|
|
On Linux, the orchestrator binds to all interfaces (`0.0.0.0`) to allow container access. On macOS/Windows, it binds to loopback (`127.0.0.1`) since Docker Desktop routes through the VM.
|