agenthub-multiagent-mcp 1.1.2 → 1.1.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/src/client.ts CHANGED
@@ -1,286 +1,293 @@
1
- /**
2
- * HTTP client for AgentHub API
3
- */
4
-
5
- export interface Agent {
6
- id: string;
7
- name: string;
8
- owner: string;
9
- model: string;
10
- model_provider: string;
11
- status: "online" | "busy" | "offline";
12
- working_dir: string;
13
- current_task: string;
14
- task_started_at?: string;
15
- channels: string[];
16
- registered_at: string;
17
- last_heartbeat: string;
18
- }
19
-
20
- export interface PendingTask {
21
- id: string;
22
- assigned_to: string;
23
- assigned_by: string;
24
- assigned_by_name?: string;
25
- task: string;
26
- priority: string;
27
- status: string;
28
- created_at: string;
29
- }
30
-
31
- export interface TaskCompletionResponse {
32
- task_id: string;
33
- elapsed_time: string;
34
- slack_posted: boolean;
35
- agents_notified: number;
36
- pending_tasks_count: number;
37
- }
38
-
39
- export interface Message {
40
- id: string;
41
- from_agent: string;
42
- to_agent?: string;
43
- to_channel?: string;
44
- broadcast: boolean;
45
- type: "task" | "status" | "question" | "response" | "context";
46
- subject: string;
47
- body: string;
48
- reply_to?: string;
49
- status: "pending" | "delivered" | "read" | "responded";
50
- priority: "normal" | "high" | "urgent";
51
- created_at: string;
52
- delivered_at?: string;
53
- read_at?: string;
54
- }
55
-
56
- export interface Channel {
57
- name: string;
58
- description: string;
59
- members: string[];
60
- member_count: number;
61
- created_at: string;
62
- }
63
-
64
- export class ApiClient {
65
- private baseUrl: string;
66
- private apiKey: string;
67
-
68
- constructor(baseUrl: string, apiKey: string) {
69
- this.baseUrl = baseUrl.replace(/\/$/, "");
70
- this.apiKey = apiKey;
71
- }
72
-
73
- private async request<T>(
74
- method: string,
75
- path: string,
76
- body?: unknown
77
- ): Promise<T> {
78
- const url = `${this.baseUrl}${path}`;
79
-
80
- const response = await fetch(url, {
81
- method,
82
- headers: {
83
- "Content-Type": "application/json",
84
- "X-API-Key": this.apiKey,
85
- },
86
- body: body ? JSON.stringify(body) : undefined,
87
- });
88
-
89
- const data = await response.json() as Record<string, unknown>;
90
-
91
- if (!response.ok) {
92
- const message = typeof data.message === 'string' ? data.message : `Request failed: ${response.status}`;
93
- throw new Error(message);
94
- }
95
-
96
- return data as T;
97
- }
98
-
99
- // Agent methods
100
- async registerAgent(
101
- id: string,
102
- name?: string,
103
- owner?: string,
104
- workingDir?: string,
105
- model?: string
106
- ): Promise<{
107
- agent_id: string;
108
- token: string;
109
- model: string;
110
- model_provider: string;
111
- registered_at: string;
112
- slack_notified: boolean;
113
- pending_tasks_count: number;
114
- unread_messages_count: number;
115
- }> {
116
- return this.request("POST", "/agents/register", {
117
- id,
118
- name,
119
- owner,
120
- working_dir: workingDir,
121
- model,
122
- });
123
- }
124
-
125
- async reconnectAgent(
126
- agentId: string,
127
- token: string,
128
- owner?: string
129
- ): Promise<{
130
- reconnected: boolean;
131
- agent_id: string;
132
- was_offline: boolean;
133
- pending_tasks_count: number;
134
- unread_messages_count: number;
135
- slack_notified: boolean;
136
- }> {
137
- return this.request("POST", "/agents/reconnect", {
138
- agent_id: agentId,
139
- token,
140
- owner,
141
- });
142
- }
143
-
144
- async startWork(
145
- agentId: string,
146
- task: string,
147
- project?: string
148
- ): Promise<{ acknowledged: boolean; slack_posted: boolean }> {
149
- return this.request("POST", `/agents/${agentId}/start-work`, {
150
- task,
151
- project,
152
- });
153
- }
154
-
155
- async heartbeat(
156
- agentId: string,
157
- status?: "online" | "busy"
158
- ): Promise<{ acknowledged: boolean; timestamp: string }> {
159
- return this.request("POST", `/agents/${agentId}/heartbeat`, { status });
160
- }
161
-
162
- async disconnect(agentId: string): Promise<{ unregistered: boolean }> {
163
- return this.request("DELETE", `/agents/${agentId}`);
164
- }
165
-
166
- async getAgent(agentId: string): Promise<Agent> {
167
- return this.request("GET", `/agents/${agentId}`);
168
- }
169
-
170
- async listAgents(status?: string): Promise<{ agents: Agent[]; total: number }> {
171
- const query = status ? `?status=${status}` : "";
172
- return this.request("GET", `/agents${query}`);
173
- }
174
-
175
- // Message methods
176
- async sendMessage(params: {
177
- from_agent?: string;
178
- to_agent?: string;
179
- to_channel?: string;
180
- broadcast?: boolean;
181
- type: string;
182
- subject: string;
183
- body: string;
184
- reply_to?: string;
185
- priority?: string;
186
- }): Promise<{ message_id: string; status: string; created_at: string }> {
187
- return this.request("POST", "/messages", params);
188
- }
189
-
190
- async getInbox(
191
- agentId: string,
192
- unreadOnly?: boolean,
193
- limit?: number
194
- ): Promise<{ messages: Message[]; total: number }> {
195
- const params = new URLSearchParams();
196
- if (unreadOnly) params.set("unread_only", "true");
197
- if (limit) params.set("limit", String(limit));
198
- const query = params.toString() ? `?${params}` : "";
199
- return this.request("GET", `/messages/inbox/${agentId}${query}`);
200
- }
201
-
202
- async markRead(messageId: string): Promise<{ updated: boolean }> {
203
- return this.request("PATCH", `/messages/${messageId}/status`, {
204
- status: "read",
205
- });
206
- }
207
-
208
- async reply(
209
- messageId: string,
210
- fromAgent: string,
211
- body: string
212
- ): Promise<{ message_id: string }> {
213
- // Get original message to find recipient
214
- const original = await this.request<Message>("GET", `/messages/${messageId}`);
215
-
216
- return this.request("POST", "/messages", {
217
- from_agent: fromAgent,
218
- to_agent: original.from_agent,
219
- type: "response",
220
- subject: `Re: ${original.subject}`,
221
- body,
222
- reply_to: messageId,
223
- });
224
- }
225
-
226
- // Channel methods
227
- async listChannels(): Promise<{ channels: Channel[]; total: number }> {
228
- return this.request("GET", "/channels");
229
- }
230
-
231
- async joinChannel(
232
- channelName: string,
233
- agentId: string
234
- ): Promise<{ subscribed: boolean }> {
235
- return this.request("POST", `/channels/${channelName}/subscribe`, {
236
- agent_id: agentId,
237
- });
238
- }
239
-
240
- async leaveChannel(
241
- channelName: string,
242
- agentId: string
243
- ): Promise<{ unsubscribed: boolean }> {
244
- return this.request("DELETE", `/channels/${channelName}/unsubscribe/${agentId}`);
245
- }
246
-
247
- // Task completion methods
248
- async completeTask(
249
- agentId: string,
250
- params: {
251
- summary: string;
252
- outcome: "completed" | "blocked" | "partial" | "needs_review" | "handed_off";
253
- files_changed?: string[];
254
- time_spent?: string;
255
- next_steps?: string;
256
- }
257
- ): Promise<TaskCompletionResponse> {
258
- return this.request("POST", `/agents/${agentId}/complete-task`, params);
259
- }
260
-
261
- async getPendingTasks(
262
- agentId: string
263
- ): Promise<{ tasks: PendingTask[]; total: number }> {
264
- return this.request("GET", `/agents/${agentId}/pending-tasks`);
265
- }
266
-
267
- async acceptTask(
268
- agentId: string,
269
- taskId: string
270
- ): Promise<{ acknowledged: boolean; task: string; started_at: string }> {
271
- return this.request("POST", `/agents/${agentId}/accept-task`, {
272
- task_id: taskId,
273
- });
274
- }
275
-
276
- async declineTask(
277
- agentId: string,
278
- taskId: string,
279
- reason: string
280
- ): Promise<{ acknowledged: boolean }> {
281
- return this.request("POST", `/agents/${agentId}/decline-task`, {
282
- task_id: taskId,
283
- reason,
284
- });
285
- }
286
- }
1
+ /**
2
+ * HTTP client for AgentHub API
3
+ */
4
+
5
+ export interface Agent {
6
+ id: string;
7
+ name: string;
8
+ owner: string;
9
+ model: string;
10
+ model_provider: string;
11
+ status: "online" | "busy" | "offline";
12
+ working_dir: string;
13
+ current_task: string;
14
+ task_started_at?: string;
15
+ channels: string[];
16
+ registered_at: string;
17
+ last_heartbeat: string;
18
+ }
19
+
20
+ export interface PendingTask {
21
+ id: string;
22
+ assigned_to: string;
23
+ assigned_by: string;
24
+ assigned_by_name?: string;
25
+ task: string;
26
+ priority: string;
27
+ status: string;
28
+ created_at: string;
29
+ }
30
+
31
+ export interface TaskCompletionResponse {
32
+ task_id: string;
33
+ elapsed_time: string;
34
+ slack_posted: boolean;
35
+ agents_notified: number;
36
+ pending_tasks_count: number;
37
+ }
38
+
39
+ export interface Message {
40
+ id: string;
41
+ from_agent: string;
42
+ to_agent?: string;
43
+ to_channel?: string;
44
+ broadcast: boolean;
45
+ type: "task" | "status" | "question" | "response" | "context";
46
+ subject: string;
47
+ body: string;
48
+ reply_to?: string;
49
+ status: "pending" | "delivered" | "read" | "responded";
50
+ priority: "normal" | "high" | "urgent";
51
+ created_at: string;
52
+ delivered_at?: string;
53
+ read_at?: string;
54
+ }
55
+
56
+ export interface Channel {
57
+ name: string;
58
+ description: string;
59
+ members: string[];
60
+ member_count: number;
61
+ created_at: string;
62
+ }
63
+
64
+ export class ApiClient {
65
+ private baseUrl: string;
66
+ private apiKey: string;
67
+
68
+ constructor(baseUrl: string, apiKey: string) {
69
+ this.baseUrl = baseUrl.replace(/\/$/, "");
70
+ this.apiKey = apiKey;
71
+ }
72
+
73
+ private async request<T>(
74
+ method: string,
75
+ path: string,
76
+ body?: unknown
77
+ ): Promise<T> {
78
+ const url = `${this.baseUrl}${path}`;
79
+
80
+ const response = await fetch(url, {
81
+ method,
82
+ headers: {
83
+ "Content-Type": "application/json",
84
+ "X-API-Key": this.apiKey,
85
+ },
86
+ body: body ? JSON.stringify(body) : undefined,
87
+ });
88
+
89
+ const data = await response.json() as Record<string, unknown>;
90
+
91
+ if (!response.ok) {
92
+ const message = typeof data.message === 'string' ? data.message : `Request failed: ${response.status}`;
93
+ throw new Error(message);
94
+ }
95
+
96
+ return data as T;
97
+ }
98
+
99
+ // Agent methods
100
+ async registerAgent(
101
+ id: string,
102
+ name?: string,
103
+ owner?: string,
104
+ workingDir?: string,
105
+ model?: string
106
+ ): Promise<{
107
+ agent_id: string;
108
+ token: string;
109
+ model: string;
110
+ model_provider: string;
111
+ registered_at: string;
112
+ slack_notified: boolean;
113
+ pending_tasks_count: number;
114
+ unread_messages_count: number;
115
+ }> {
116
+ return this.request("POST", "/agents/register", {
117
+ id,
118
+ name,
119
+ owner,
120
+ working_dir: workingDir,
121
+ model,
122
+ });
123
+ }
124
+
125
+ async reconnectAgent(
126
+ agentId: string,
127
+ token: string,
128
+ owner?: string,
129
+ model?: string
130
+ ): Promise<{
131
+ reconnected: boolean;
132
+ agent_id: string;
133
+ was_offline: boolean;
134
+ pending_tasks_count: number;
135
+ unread_messages_count: number;
136
+ slack_notified: boolean;
137
+ }> {
138
+ return this.request("POST", "/agents/reconnect", {
139
+ agent_id: agentId,
140
+ token,
141
+ owner,
142
+ model,
143
+ });
144
+ }
145
+
146
+ async startWork(
147
+ agentId: string,
148
+ task: string,
149
+ project?: string
150
+ ): Promise<{ acknowledged: boolean; slack_posted: boolean }> {
151
+ return this.request("POST", `/agents/${agentId}/start-work`, {
152
+ task,
153
+ project,
154
+ });
155
+ }
156
+
157
+ async heartbeat(
158
+ agentId: string,
159
+ status?: "online" | "busy"
160
+ ): Promise<{
161
+ acknowledged: boolean;
162
+ timestamp: string;
163
+ pending_tasks_count: number;
164
+ unread_messages_count: number;
165
+ }> {
166
+ return this.request("POST", `/agents/${agentId}/heartbeat`, { status });
167
+ }
168
+
169
+ async disconnect(agentId: string): Promise<{ unregistered: boolean }> {
170
+ return this.request("DELETE", `/agents/${agentId}`);
171
+ }
172
+
173
+ async getAgent(agentId: string): Promise<Agent> {
174
+ return this.request("GET", `/agents/${agentId}`);
175
+ }
176
+
177
+ async listAgents(status?: string): Promise<{ agents: Agent[]; total: number }> {
178
+ const query = status ? `?status=${status}` : "";
179
+ return this.request("GET", `/agents${query}`);
180
+ }
181
+
182
+ // Message methods
183
+ async sendMessage(params: {
184
+ from_agent?: string;
185
+ to_agent?: string;
186
+ to_channel?: string;
187
+ broadcast?: boolean;
188
+ type: string;
189
+ subject: string;
190
+ body: string;
191
+ reply_to?: string;
192
+ priority?: string;
193
+ }): Promise<{ message_id: string; status: string; created_at: string }> {
194
+ return this.request("POST", "/messages", params);
195
+ }
196
+
197
+ async getInbox(
198
+ agentId: string,
199
+ unreadOnly?: boolean,
200
+ limit?: number
201
+ ): Promise<{ messages: Message[]; total: number }> {
202
+ const params = new URLSearchParams();
203
+ if (unreadOnly) params.set("unread_only", "true");
204
+ if (limit) params.set("limit", String(limit));
205
+ const query = params.toString() ? `?${params}` : "";
206
+ return this.request("GET", `/messages/inbox/${agentId}${query}`);
207
+ }
208
+
209
+ async markRead(messageId: string): Promise<{ updated: boolean }> {
210
+ return this.request("PATCH", `/messages/${messageId}/status`, {
211
+ status: "read",
212
+ });
213
+ }
214
+
215
+ async reply(
216
+ messageId: string,
217
+ fromAgent: string,
218
+ body: string
219
+ ): Promise<{ message_id: string }> {
220
+ // Get original message to find recipient
221
+ const original = await this.request<Message>("GET", `/messages/${messageId}`);
222
+
223
+ return this.request("POST", "/messages", {
224
+ from_agent: fromAgent,
225
+ to_agent: original.from_agent,
226
+ type: "response",
227
+ subject: `Re: ${original.subject}`,
228
+ body,
229
+ reply_to: messageId,
230
+ });
231
+ }
232
+
233
+ // Channel methods
234
+ async listChannels(): Promise<{ channels: Channel[]; total: number }> {
235
+ return this.request("GET", "/channels");
236
+ }
237
+
238
+ async joinChannel(
239
+ channelName: string,
240
+ agentId: string
241
+ ): Promise<{ subscribed: boolean }> {
242
+ return this.request("POST", `/channels/${channelName}/subscribe`, {
243
+ agent_id: agentId,
244
+ });
245
+ }
246
+
247
+ async leaveChannel(
248
+ channelName: string,
249
+ agentId: string
250
+ ): Promise<{ unsubscribed: boolean }> {
251
+ return this.request("DELETE", `/channels/${channelName}/unsubscribe/${agentId}`);
252
+ }
253
+
254
+ // Task completion methods
255
+ async completeTask(
256
+ agentId: string,
257
+ params: {
258
+ summary: string;
259
+ outcome: "completed" | "blocked" | "partial" | "needs_review" | "handed_off";
260
+ files_changed?: string[];
261
+ time_spent?: string;
262
+ next_steps?: string;
263
+ }
264
+ ): Promise<TaskCompletionResponse> {
265
+ return this.request("POST", `/agents/${agentId}/complete-task`, params);
266
+ }
267
+
268
+ async getPendingTasks(
269
+ agentId: string
270
+ ): Promise<{ tasks: PendingTask[]; total: number }> {
271
+ return this.request("GET", `/agents/${agentId}/pending-tasks`);
272
+ }
273
+
274
+ async acceptTask(
275
+ agentId: string,
276
+ taskId: string
277
+ ): Promise<{ acknowledged: boolean; task: string; started_at: string }> {
278
+ return this.request("POST", `/agents/${agentId}/accept-task`, {
279
+ task_id: taskId,
280
+ });
281
+ }
282
+
283
+ async declineTask(
284
+ agentId: string,
285
+ taskId: string,
286
+ reason: string
287
+ ): Promise<{ acknowledged: boolean }> {
288
+ return this.request("POST", `/agents/${agentId}/decline-task`, {
289
+ task_id: taskId,
290
+ reason,
291
+ });
292
+ }
293
+ }