Skip to content

Commit 93aa4a8

Browse files
committed
remove redundant functions in a2a/chat.js
1 parent 76a56ab commit 93aa4a8

File tree

1 file changed

+31
-208
lines changed

1 file changed

+31
-208
lines changed

api/server/controllers/a2a/chat.js

Lines changed: 31 additions & 208 deletions
Original file line numberDiff line numberDiff line change
@@ -3,214 +3,6 @@ const { sendEvent } = require('@librechat/api');
33
const { saveMessage, saveConvo } = require('~/models');
44
const discoveryService = require('../../services/A2ADiscoveryService');
55

6-
/**
7-
* Poll for task completion and stream updates
8-
*/
9-
const pollTaskCompletion = async (client, taskId, agent, contextId, messageId, res, streaming, req) => {
10-
const maxPolls = 60; // Maximum 5 minutes (60 * 5s)
11-
let pollCount = 0;
12-
13-
const poll = async () => {
14-
try {
15-
if (pollCount >= maxPolls) {
16-
throw new Error('Task polling timeout');
17-
}
18-
19-
const taskStatus = await client.getTaskStatus(taskId);
20-
pollCount++;
21-
22-
// Send status update
23-
if (streaming) {
24-
sendEvent(res, {
25-
type: 'task_update',
26-
taskId,
27-
status: taskStatus.status,
28-
statusMessage: taskStatus.statusMessage,
29-
pollCount,
30-
});
31-
}
32-
33-
// Check if task is complete
34-
const terminalStates = ['completed', 'failed', 'canceled'];
35-
if (terminalStates.includes(taskStatus.status)) {
36-
return handleTaskCompletion(taskStatus, agent, contextId, messageId, res, streaming, req);
37-
}
38-
39-
// Continue polling
40-
setTimeout(poll, 5000); // Poll every 5 seconds
41-
42-
} catch (error) {
43-
console.error(`Task polling error for ${taskId}:`, error);
44-
throw error;
45-
}
46-
};
47-
48-
// Start polling
49-
setTimeout(poll, 2000); // Initial delay of 2 seconds
50-
};
51-
52-
/**
53-
* Handle task completion
54-
*/
55-
const handleTaskCompletion = async (taskStatus, agent, contextId, messageId, res, streaming, req) => {
56-
const responseMessageId = uuidv4();
57-
58-
// Extract response content from task
59-
let responseText = 'Task completed';
60-
if (taskStatus.history && taskStatus.history.length > 0) {
61-
const lastMessage = taskStatus.history[taskStatus.history.length - 1];
62-
if (lastMessage.role === 'agent' && lastMessage.parts?.[0]?.content) {
63-
responseText = lastMessage.parts[0].content;
64-
}
65-
}
66-
67-
// Stream response content if available
68-
if (streaming && responseText !== 'Task completed') {
69-
await streamContent(responseText, res, responseMessageId);
70-
}
71-
72-
// Send final response using LibreChat's expected format
73-
const finalResponse = {
74-
final: true,
75-
conversation: {
76-
conversationId: contextId,
77-
title: `A2A Task with ${agent.name}`,
78-
},
79-
requestMessage: {
80-
messageId,
81-
conversationId: contextId,
82-
parentMessageId: null,
83-
role: 'user',
84-
text: message,
85-
},
86-
responseMessage: {
87-
messageId: responseMessageId,
88-
conversationId: contextId,
89-
parentMessageId: messageId,
90-
role: 'assistant',
91-
text: responseText,
92-
model: `a2a-${agent.id}`,
93-
endpoint: 'a2a',
94-
metadata: {
95-
agentId: agent.id,
96-
agentName: agent.name,
97-
taskId: taskStatus.id,
98-
taskStatus: taskStatus.status,
99-
artifacts: taskStatus.artifacts || [],
100-
},
101-
},
102-
};
103-
104-
if (streaming) {
105-
sendEvent(res, finalResponse);
106-
107-
// Save messages to database after successful task completion
108-
try {
109-
// Save user message
110-
await saveMessage(req, {
111-
messageId,
112-
conversationId: contextId,
113-
parentMessageId: null,
114-
role: 'user',
115-
text: finalResponse.requestMessage.text,
116-
user: req.user?.id,
117-
endpoint: 'a2a',
118-
model: `a2a-${agent.id}`,
119-
isCreatedByUser: true,
120-
}, { context: 'A2A Task Chat - User Message' });
121-
122-
// Save agent response
123-
const agentMessage = await saveMessage(req, {
124-
messageId: responseMessageId,
125-
conversationId: contextId,
126-
parentMessageId: messageId,
127-
role: 'assistant',
128-
text: responseText,
129-
user: req.user?.id,
130-
endpoint: 'a2a',
131-
model: `a2a-${agent.id}`,
132-
metadata: {
133-
agentId: agent.id,
134-
agentName: agent.name,
135-
taskId: taskStatus.id,
136-
taskStatus: taskStatus.status,
137-
artifacts: taskStatus.artifacts || [],
138-
},
139-
}, { context: 'A2A Task Chat - Agent Response' });
140-
141-
// Save conversation metadata
142-
await saveConvo(req, {
143-
conversationId: contextId,
144-
endpoint: 'a2a',
145-
model: `a2a-${agent.id}`,
146-
title: `A2A Task with ${agent.name}`,
147-
}, { context: 'A2A Task Chat - Conversation' });
148-
149-
} catch (saveError) {
150-
console.error('Error saving A2A task messages:', saveError);
151-
// Don't fail the request if saving fails
152-
}
153-
}
154-
155-
return finalResponse;
156-
};
157-
158-
/**
159-
* Stream content in chunks using LibreChat's expected format
160-
*/
161-
const streamContent = async (content, res, messageId) => {
162-
const words = content.split(' ');
163-
const chunkSize = 3; // Stream 3 words at a time
164-
let accumulatedText = '';
165-
166-
for (let i = 0; i < words.length; i += chunkSize) {
167-
const chunk = words.slice(i, i + chunkSize).join(' ');
168-
accumulatedText += (i === 0 ? chunk : ' ' + chunk);
169-
170-
// Use LibreChat's expected streaming format
171-
sendEvent(res, {
172-
message: true,
173-
initial: i === 0,
174-
messageId,
175-
text: accumulatedText,
176-
});
177-
178-
// Add delay to simulate typing
179-
await new Promise(resolve => setTimeout(resolve, 100));
180-
}
181-
};
182-
183-
/**
184-
* Get available A2A agents
185-
*/
186-
const getA2AAgents = async (req, res) => {
187-
try {
188-
const agents = discoveryService.getRegisteredAgents();
189-
190-
// Format agents for client consumption
191-
const formattedAgents = agents.map(agent => ({
192-
id: agent.id,
193-
name: agent.name,
194-
description: agent.description,
195-
status: agent.status,
196-
capabilities: agent.agentCard?.capabilities || {},
197-
skills: agent.agentCard?.skills || [],
198-
transport: agent.preferredTransport,
199-
lastHealthCheck: agent.lastHealthCheck,
200-
createdAt: agent.createdAt,
201-
}));
202-
203-
res.json({ agents: formattedAgents });
204-
205-
} catch (error) {
206-
console.error('Error fetching A2A agents:', error);
207-
res.status(500).json({
208-
error: 'Failed to fetch A2A agents',
209-
message: error.message
210-
});
211-
}
212-
};
213-
2146
/**
2157
* Register a new A2A agent
2168
*/
@@ -270,6 +62,37 @@ const unregisterA2AAgent = async (req, res) => {
27062
}
27163
};
27264

65+
/**
66+
* Get available A2A agents
67+
*/
68+
const getA2AAgents = async (req, res) => {
69+
try {
70+
const agents = discoveryService.getRegisteredAgents();
71+
72+
// Format agents for client consumption
73+
const formattedAgents = agents.map(agent => ({
74+
id: agent.id,
75+
name: agent.name,
76+
description: agent.description,
77+
status: agent.status,
78+
capabilities: agent.agentCard?.capabilities || {},
79+
skills: agent.agentCard?.skills || [],
80+
transport: agent.preferredTransport,
81+
lastHealthCheck: agent.lastHealthCheck,
82+
createdAt: agent.createdAt,
83+
}));
84+
85+
res.json({ agents: formattedAgents });
86+
87+
} catch (error) {
88+
console.error('Error fetching A2A agents:', error);
89+
res.status(500).json({
90+
error: 'Failed to fetch A2A agents',
91+
message: error.message
92+
});
93+
}
94+
};
95+
27396
/**
27497
* Get A2A agent details
27598
*/

0 commit comments

Comments
 (0)