feat(openclaw): Phase 2 — heartbeat endpoint + iAgent OpenClaw deployment awareness

- agent-instance.controller: POST :id/heartbeat — bridge calls this every 60s;
  auto-transitions status from deploying→running when gateway is confirmed connected
- system-prompt-builder: teach iAgent about OpenClaw deployment capability:
  create/list/stop/remove instance API endpoints, when to trigger deployment,
  and what to tell users about channel connectivity (Telegram/WhatsApp etc.)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
hailin 2026-03-07 11:17:35 -08:00
parent 7d5840c245
commit 2086eb8109
2 changed files with 30 additions and 2 deletions

View File

@ -30,8 +30,20 @@ export class SystemPromptBuilder {
// Base instruction
parts.push(
'You are IT0, an AI-powered server operations assistant. ' +
'You help manage and monitor server infrastructure safely and efficiently.',
'You are iAgent, an AI-powered server cluster operations assistant built on IT0. ' +
'You help users manage server infrastructure, deploy AI agents, and automate operations safely and efficiently.\n\n' +
'## OpenClaw Agent Deployment\n' +
'You can deploy real OpenClaw AI agent instances for users. OpenClaw is an open-source autonomous AI agent.\n' +
'To deploy an OpenClaw instance, call the IT0 API:\n' +
' POST /api/v1/agent/instances\n' +
' Body: { "name": "<user-given name>", "userId": "<user id>", "usePool": true }\n' +
'The instance will be deployed on a pool server automatically. After creation, the user can connect\n' +
'their OpenClaw to Telegram, WhatsApp, or other channels via the channel configuration.\n' +
'To list existing instances: GET /api/v1/agent/instances\n' +
'To stop an instance: PUT /api/v1/agent/instances/:id/stop\n' +
'To remove an instance: DELETE /api/v1/agent/instances/:id\n\n' +
'When a user says they want to create an OpenClaw, a personal AI agent, or an autonomous agent,\n' +
'confirm their desired name, then call the deployment API and report the result.',
);
// Tenant context

View File

@ -112,6 +112,22 @@ export class AgentInstanceController {
return this.sanitize(await this.instanceRepo.save(inst));
}
// Called by it0-bridge every 60s to confirm instance is healthy
@Post(':id/heartbeat')
async heartbeat(
@Param('id') id: string,
@Body() body: { gatewayConnected: boolean; uptime: number },
) {
const inst = await this.instanceRepo.findById(id);
if (!inst) return { ok: false };
if (body.gatewayConnected && inst.status !== 'running') {
inst.status = 'running';
await this.instanceRepo.save(inst);
}
return { ok: true };
}
@Delete(':id')
async remove(@Param('id') id: string) {
const inst = await this.instanceRepo.findById(id);