feat: Add GET /api/status endpoint with job stats and update PROJECT.md
This commit is contained in:
141
PROJECT.md
141
PROJECT.md
@@ -6,54 +6,141 @@ The `vibn-agent-runner` is a service responsible for executing tasks or "agents"
|
|||||||
|
|
||||||
## API Endpoints
|
## API Endpoints
|
||||||
|
|
||||||
(Note: These are example endpoints. Please refer to the source code or API documentation for exact details.)
|
### `GET /api/status`
|
||||||
|
|
||||||
### `POST /run-agent`
|
Retrieves server status and job statistics.
|
||||||
|
|
||||||
Initiates the execution of an agent.
|
- **Method:** `GET`
|
||||||
|
- **URL:** `/api/status`
|
||||||
|
- **Response Body Example:**
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"total_jobs": 100,
|
||||||
|
"by_status": {
|
||||||
|
"queued": 10,
|
||||||
|
"running": 5,
|
||||||
|
"completed": 80,
|
||||||
|
"failed": 5
|
||||||
|
},
|
||||||
|
"uptime_seconds": 3600,
|
||||||
|
"agents": ["Coder", "PM", "Marketing"]
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### `GET /health`
|
||||||
|
|
||||||
|
Health check endpoint.
|
||||||
|
|
||||||
|
- **Method:** `GET`
|
||||||
|
- **URL:** `/health`
|
||||||
|
- **Response Body Example:**
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"status": "ok",
|
||||||
|
"timestamp": "2023-10-27T10:00:00.000Z"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### `GET /api/agents`
|
||||||
|
|
||||||
|
Lists available agents.
|
||||||
|
|
||||||
|
- **Method:** `GET`
|
||||||
|
- **URL:** `/api/agents`
|
||||||
|
- **Response Body Example:**
|
||||||
|
```json
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"name": "Coder",
|
||||||
|
"description": "An agent that writes and modifies code.",
|
||||||
|
"tools": ["read_file", "write_file", "replace_in_file", "list_directory", "find_files", "search_code", "execute_command", "git_commit_and_push", "gitea_create_issue", "gitea_list_issues", "gitea_close_issue"]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
```
|
||||||
|
|
||||||
|
### `POST /api/agent/run`
|
||||||
|
|
||||||
|
Submits a new job to run an agent.
|
||||||
|
|
||||||
- **Method:** `POST`
|
- **Method:** `POST`
|
||||||
- **URL:** `/run-agent`
|
- **URL:** `/api/agent/run`
|
||||||
- **Request Body Example:**
|
- **Request Body Example:**
|
||||||
```json
|
```json
|
||||||
{
|
{
|
||||||
"agentId": "your-agent-id",
|
"agent": "Coder",
|
||||||
"payload": {
|
"task": "Fix bug in user authentication",
|
||||||
"param1": "value1",
|
"repo": "owner/repo-name"
|
||||||
"param2": "value2"
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
- **Response Body Example (Success):**
|
- **Response Body Example (Success):**
|
||||||
```json
|
```json
|
||||||
{
|
{
|
||||||
"status": "success",
|
"jobId": "unique-job-id",
|
||||||
"runId": "unique-run-id",
|
"status": "queued"
|
||||||
"message": "Agent execution started."
|
|
||||||
}
|
|
||||||
```
|
|
||||||
- **Response Body Example (Error):**
|
|
||||||
```json
|
|
||||||
{
|
|
||||||
"status": "error",
|
|
||||||
"message": "Failed to start agent execution.",
|
|
||||||
"details": "Error message details"
|
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
### `GET /agent-status/{runId}`
|
### `GET /api/jobs/:id`
|
||||||
|
|
||||||
Retrieves the status of a running or completed agent.
|
Retrieves the status of a specific job.
|
||||||
|
|
||||||
- **Method:** `GET`
|
- **Method:** `GET`
|
||||||
- **URL:** `/agent-status/{runId}`
|
- **URL:** `/api/jobs/:id`
|
||||||
- **Response Body Example:**
|
- **Response Body Example:**
|
||||||
```json
|
```json
|
||||||
{
|
{
|
||||||
"runId": "unique-run-id",
|
"id": "unique-job-id",
|
||||||
"status": "running", // or "completed", "failed"
|
"agent": "Coder",
|
||||||
"progress": "50%",
|
"task": "Fix bug in user authentication",
|
||||||
"results": {} // or actual results if completed
|
"repo": "owner/repo-name",
|
||||||
|
"status": "running",
|
||||||
|
"progress": "Executing tests...",
|
||||||
|
"createdAt": "2023-10-27T10:00:00.000Z"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### `GET /api/jobs`
|
||||||
|
|
||||||
|
Lists recent jobs.
|
||||||
|
|
||||||
|
- **Method:** `GET`
|
||||||
|
- **URL:** `/api/jobs`
|
||||||
|
- **Query Parameters:**
|
||||||
|
- `limit`: (Optional) Number of jobs to return (default: 20)
|
||||||
|
- **Response Body Example:**
|
||||||
|
```json
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"id": "job-id-1",
|
||||||
|
"agent": "Coder",
|
||||||
|
"task": "Implement feature X",
|
||||||
|
"status": "completed"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "job-id-2",
|
||||||
|
"agent": "PM",
|
||||||
|
"task": "Write project brief",
|
||||||
|
"status": "running"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
```
|
||||||
|
|
||||||
|
### `POST /webhook/gitea`
|
||||||
|
|
||||||
|
Gitea webhook endpoint to trigger agents from issue events.
|
||||||
|
|
||||||
|
- **Method:** `POST`
|
||||||
|
- **URL:** `/webhook/gitea`
|
||||||
|
- **Headers:**
|
||||||
|
- `X-Gitea-Event`: e.g., `issues`
|
||||||
|
- `X-Gitea-Signature`: HMAC-SHA256 signature (if `WEBHOOK_SECRET` is set)
|
||||||
|
- **Request Body:** Gitea webhook payload (JSON)
|
||||||
|
- **Response Body Example:**
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"jobId": "unique-job-id",
|
||||||
|
"agent": "Coder",
|
||||||
|
"event": "issues"
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|||||||
@@ -12,6 +12,8 @@ import { ToolContext } from './tools';
|
|||||||
const app = express();
|
const app = express();
|
||||||
app.use(cors());
|
app.use(cors());
|
||||||
|
|
||||||
|
const startTime = new Date();
|
||||||
|
|
||||||
// Raw body capture for webhook HMAC — must come before express.json()
|
// Raw body capture for webhook HMAC — must come before express.json()
|
||||||
app.use('/webhook/gitea', express.raw({ type: '*/*' }));
|
app.use('/webhook/gitea', express.raw({ type: '*/*' }));
|
||||||
|
|
||||||
@@ -87,6 +89,33 @@ app.get('/api/agents', (_req: Request, res: Response) => {
|
|||||||
res.json(agents);
|
res.json(agents);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Get server status and job statistics
|
||||||
|
app.get('/api/status', (_req: Request, res: Response) => {
|
||||||
|
const allJobs = listJobs(Infinity);
|
||||||
|
const total_jobs = allJobs.length;
|
||||||
|
|
||||||
|
const by_status: { [key: string]: number } = {
|
||||||
|
queued: 0,
|
||||||
|
running: 0,
|
||||||
|
completed: 0,
|
||||||
|
failed: 0,
|
||||||
|
};
|
||||||
|
for (const job of allJobs) {
|
||||||
|
by_status[job.status] = (by_status[job.status] || 0) + 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
const uptime_seconds = Math.floor((new Date().getTime() - startTime.getTime()) / 1000);
|
||||||
|
|
||||||
|
const agents = Object.values(AGENTS).map(a => a.name);
|
||||||
|
|
||||||
|
res.json({
|
||||||
|
total_jobs,
|
||||||
|
by_status,
|
||||||
|
uptime_seconds,
|
||||||
|
agents,
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
// Submit a new job
|
// Submit a new job
|
||||||
app.post('/api/agent/run', async (req: Request, res: Response) => {
|
app.post('/api/agent/run', async (req: Request, res: Response) => {
|
||||||
const { agent: agentName, task, repo } = req.body as { agent?: string; task?: string; repo?: string };
|
const { agent: agentName, task, repo } = req.body as { agent?: string; task?: string; repo?: string };
|
||||||
|
|||||||
Reference in New Issue
Block a user