fix: align with AGENT-PROTOCOL v1.0 — correct WS types, heartbeat, REST auth
This commit is contained in:
parent
368b9abf69
commit
f97aa64142
@ -96,7 +96,7 @@ export class EventRouter {
|
||||
if (collectedText.trim()) {
|
||||
this.log.info('│ → Sending result comment (%d chars)...', collectedText.trim().length);
|
||||
this.log.info('│ Result preview: %s', collectedText.trim().slice(0, 300));
|
||||
await this.client.sendMessage({ task_id: task.id, content: collectedText.trim() }).catch((err) => {
|
||||
await this.client.sendMessage({ task_id: task.id, content: collectedText.trim() }, this.config.slug).catch((err) => {
|
||||
this.log.error({ err, taskId: task.id }, 'Failed to add comment');
|
||||
});
|
||||
}
|
||||
@ -114,7 +114,7 @@ export class EventRouter {
|
||||
await this.client.sendMessage({
|
||||
task_id: task.id,
|
||||
content: `Agent error: ${err instanceof Error ? err.message : String(err)}`,
|
||||
}).catch(() => {});
|
||||
}, this.config.slug).catch(() => {});
|
||||
} finally {
|
||||
this.activeTasks--;
|
||||
this.taskTracker.removeTask(task.id);
|
||||
@ -164,11 +164,11 @@ export class EventRouter {
|
||||
if (collectedText.trim()) {
|
||||
this.log.info('│ → Sending reply (%d chars): %s', collectedText.trim().length, collectedText.trim().slice(0, 200));
|
||||
if (taskId) {
|
||||
await this.client.sendMessage({ task_id: taskId, content: collectedText.trim() }).catch((err) => {
|
||||
await this.client.sendMessage({ task_id: taskId, content: collectedText.trim() }, this.config.slug).catch((err) => {
|
||||
this.log.error({ err, taskId }, 'Failed to send task comment reply');
|
||||
});
|
||||
} else if (chatId) {
|
||||
await this.client.sendMessage({ chat_id: chatId, content: collectedText.trim() }).catch((err) => {
|
||||
await this.client.sendMessage({ chat_id: chatId, content: collectedText.trim() }, this.config.slug).catch((err) => {
|
||||
this.log.error({ err, chatId }, 'Failed to send chat reply');
|
||||
});
|
||||
}
|
||||
|
||||
@ -43,15 +43,8 @@ export class TrackerClient {
|
||||
}
|
||||
|
||||
// --- Agent lifecycle ---
|
||||
|
||||
async register(payload: RegistrationPayload): Promise<void> {
|
||||
this.log.info({ slug: payload.slug }, 'Registering agent');
|
||||
await this.request('POST', '/api/v1/agents/register', payload);
|
||||
}
|
||||
|
||||
async heartbeat(payload: HeartbeatPayload): Promise<void> {
|
||||
await this.request('POST', '/api/v1/agents/heartbeat', payload);
|
||||
}
|
||||
// Registration: done via UI (Settings → Agents) or POST /api/v1/members
|
||||
// Heartbeat: done via WebSocket only ({"type": "heartbeat", "status": "online"})
|
||||
|
||||
// --- Tasks ---
|
||||
|
||||
@ -104,9 +97,13 @@ export class TrackerClient {
|
||||
|
||||
// --- Messages (unified: chat + task comments) ---
|
||||
|
||||
async sendMessage(payload: { chat_id?: string; task_id?: string; content: string; mentions?: string[] }): Promise<Record<string, unknown>> {
|
||||
async sendMessage(payload: { chat_id?: string; task_id?: string; content: string; mentions?: string[] }, agentSlug?: string): Promise<Record<string, unknown>> {
|
||||
this.log.info({ chatId: payload.chat_id, taskId: payload.task_id, contentLength: payload.content.length }, 'Sending message');
|
||||
return this.request('POST', '/api/v1/messages', payload);
|
||||
return this.request('POST', '/api/v1/messages', {
|
||||
...payload,
|
||||
author_type: 'agent',
|
||||
author_slug: agentSlug || 'agent',
|
||||
});
|
||||
}
|
||||
|
||||
async listMessages(params: Record<string, string>): Promise<Record<string, unknown>[]> {
|
||||
@ -115,14 +112,7 @@ export class TrackerClient {
|
||||
}
|
||||
|
||||
// --- Files ---
|
||||
|
||||
async uploadFile(taskId: string, filename: string, content: string): Promise<void> {
|
||||
await this.request('POST', `/api/v1/tasks/${taskId}/files`, { filename, content });
|
||||
}
|
||||
|
||||
async listTaskFiles(taskId: string): Promise<Record<string, unknown>[]> {
|
||||
return this.request('GET', `/api/v1/tasks/${taskId}/files`);
|
||||
}
|
||||
// TODO: file upload/download not implemented yet in Tracker
|
||||
|
||||
// --- Projects ---
|
||||
|
||||
|
||||
@ -98,12 +98,9 @@ export class WsClientTransport implements TaskTracker {
|
||||
|
||||
ws.on('open', () => {
|
||||
this.log.info('━━━ WS CONNECTED ━━━');
|
||||
// Send auth — use BOTH "event" and "type" for compatibility
|
||||
// Send auth — Tracker expects "type" field only
|
||||
this.send('auth', {
|
||||
token: this.config.token,
|
||||
name: this.config.name,
|
||||
slug: this.config.slug,
|
||||
capabilities: this.config.capabilities,
|
||||
});
|
||||
});
|
||||
|
||||
@ -139,11 +136,10 @@ export class WsClientTransport implements TaskTracker {
|
||||
}
|
||||
|
||||
/**
|
||||
* Send a JSON message with both "event" and "type" fields set,
|
||||
* so the tracker picks up whichever field it uses.
|
||||
* Send a JSON message with "type" field (Tracker protocol).
|
||||
*/
|
||||
private send(eventType: string, payload: Record<string, unknown> = {}): void {
|
||||
const msg = { event: eventType, type: eventType, ...payload };
|
||||
const msg = { type: eventType, ...payload };
|
||||
const json = JSON.stringify(msg);
|
||||
this.log.info('→ SEND: %s', json.slice(0, 500));
|
||||
if (this.ws?.readyState === WebSocket.OPEN) {
|
||||
@ -219,24 +215,10 @@ export class WsClientTransport implements TaskTracker {
|
||||
this.reconnectDelay = 1000;
|
||||
this.startHeartbeat();
|
||||
|
||||
// Subscribe to lobby chat
|
||||
if (this.lobbyChatId) {
|
||||
this.log.info('→ Subscribing to lobby chat: %s', this.lobbyChatId);
|
||||
this.send('chat.subscribe', { chat_id: this.lobbyChatId });
|
||||
}
|
||||
|
||||
// Subscribe to projects (try both protocols)
|
||||
// Subscribe to all projects
|
||||
for (const project of this.projects) {
|
||||
this.log.info('→ Subscribing to project: %s (%s)', project.slug, project.id);
|
||||
// WEBSOCKET-PROTOCOL.md style: subscribe with channels
|
||||
this.send('subscribe', { channels: [`project:${project.slug}`] });
|
||||
// TRACKER-PROTOCOL.md style: project.subscribe
|
||||
this.send('project.subscribe', { project_id: project.id });
|
||||
// If project has a chat_id, subscribe to it
|
||||
if (project.chat_id) {
|
||||
this.log.info('→ Subscribing to project chat: %s', project.chat_id);
|
||||
this.send('chat.subscribe', { chat_id: project.chat_id });
|
||||
}
|
||||
}
|
||||
|
||||
if (this.resolveStart) {
|
||||
@ -303,7 +285,7 @@ export class WsClientTransport implements TaskTracker {
|
||||
|
||||
private sendHeartbeat(): void {
|
||||
const status = this.currentTasks.size > 0 ? 'busy' : 'online';
|
||||
this.send('agent.heartbeat', { status, current_tasks: [...this.currentTasks] });
|
||||
this.send('heartbeat', { status });
|
||||
}
|
||||
|
||||
private scheduleReconnect(): void {
|
||||
|
||||
Loading…
Reference in New Issue
Block a user