agenthub-multiagent-mcp 1.1.2 → 1.1.3

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,288 @@
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<{ acknowledged: boolean; timestamp: string }> {
161
+ return this.request("POST", `/agents/${agentId}/heartbeat`, { status });
162
+ }
163
+
164
+ async disconnect(agentId: string): Promise<{ unregistered: boolean }> {
165
+ return this.request("DELETE", `/agents/${agentId}`);
166
+ }
167
+
168
+ async getAgent(agentId: string): Promise<Agent> {
169
+ return this.request("GET", `/agents/${agentId}`);
170
+ }
171
+
172
+ async listAgents(status?: string): Promise<{ agents: Agent[]; total: number }> {
173
+ const query = status ? `?status=${status}` : "";
174
+ return this.request("GET", `/agents${query}`);
175
+ }
176
+
177
+ // Message methods
178
+ async sendMessage(params: {
179
+ from_agent?: string;
180
+ to_agent?: string;
181
+ to_channel?: string;
182
+ broadcast?: boolean;
183
+ type: string;
184
+ subject: string;
185
+ body: string;
186
+ reply_to?: string;
187
+ priority?: string;
188
+ }): Promise<{ message_id: string; status: string; created_at: string }> {
189
+ return this.request("POST", "/messages", params);
190
+ }
191
+
192
+ async getInbox(
193
+ agentId: string,
194
+ unreadOnly?: boolean,
195
+ limit?: number
196
+ ): Promise<{ messages: Message[]; total: number }> {
197
+ const params = new URLSearchParams();
198
+ if (unreadOnly) params.set("unread_only", "true");
199
+ if (limit) params.set("limit", String(limit));
200
+ const query = params.toString() ? `?${params}` : "";
201
+ return this.request("GET", `/messages/inbox/${agentId}${query}`);
202
+ }
203
+
204
+ async markRead(messageId: string): Promise<{ updated: boolean }> {
205
+ return this.request("PATCH", `/messages/${messageId}/status`, {
206
+ status: "read",
207
+ });
208
+ }
209
+
210
+ async reply(
211
+ messageId: string,
212
+ fromAgent: string,
213
+ body: string
214
+ ): Promise<{ message_id: string }> {
215
+ // Get original message to find recipient
216
+ const original = await this.request<Message>("GET", `/messages/${messageId}`);
217
+
218
+ return this.request("POST", "/messages", {
219
+ from_agent: fromAgent,
220
+ to_agent: original.from_agent,
221
+ type: "response",
222
+ subject: `Re: ${original.subject}`,
223
+ body,
224
+ reply_to: messageId,
225
+ });
226
+ }
227
+
228
+ // Channel methods
229
+ async listChannels(): Promise<{ channels: Channel[]; total: number }> {
230
+ return this.request("GET", "/channels");
231
+ }
232
+
233
+ async joinChannel(
234
+ channelName: string,
235
+ agentId: string
236
+ ): Promise<{ subscribed: boolean }> {
237
+ return this.request("POST", `/channels/${channelName}/subscribe`, {
238
+ agent_id: agentId,
239
+ });
240
+ }
241
+
242
+ async leaveChannel(
243
+ channelName: string,
244
+ agentId: string
245
+ ): Promise<{ unsubscribed: boolean }> {
246
+ return this.request("DELETE", `/channels/${channelName}/unsubscribe/${agentId}`);
247
+ }
248
+
249
+ // Task completion methods
250
+ async completeTask(
251
+ agentId: string,
252
+ params: {
253
+ summary: string;
254
+ outcome: "completed" | "blocked" | "partial" | "needs_review" | "handed_off";
255
+ files_changed?: string[];
256
+ time_spent?: string;
257
+ next_steps?: string;
258
+ }
259
+ ): Promise<TaskCompletionResponse> {
260
+ return this.request("POST", `/agents/${agentId}/complete-task`, params);
261
+ }
262
+
263
+ async getPendingTasks(
264
+ agentId: string
265
+ ): Promise<{ tasks: PendingTask[]; total: number }> {
266
+ return this.request("GET", `/agents/${agentId}/pending-tasks`);
267
+ }
268
+
269
+ async acceptTask(
270
+ agentId: string,
271
+ taskId: string
272
+ ): Promise<{ acknowledged: boolean; task: string; started_at: string }> {
273
+ return this.request("POST", `/agents/${agentId}/accept-task`, {
274
+ task_id: taskId,
275
+ });
276
+ }
277
+
278
+ async declineTask(
279
+ agentId: string,
280
+ taskId: string,
281
+ reason: string
282
+ ): Promise<{ acknowledged: boolean }> {
283
+ return this.request("POST", `/agents/${agentId}/decline-task`, {
284
+ task_id: taskId,
285
+ reason,
286
+ });
287
+ }
288
+ }