@loopman/langchain-sdk 1.0.9
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/LICENSE +374 -0
- package/README.md +594 -0
- package/dist/agents/loopman-agent.d.ts +29 -0
- package/dist/agents/loopman-agent.d.ts.map +1 -0
- package/dist/agents/loopman-agent.js +441 -0
- package/dist/agents/loopman-agent.js.map +1 -0
- package/dist/client/loopman-api.d.ts +123 -0
- package/dist/client/loopman-api.d.ts.map +1 -0
- package/dist/client/loopman-api.js +407 -0
- package/dist/client/loopman-api.js.map +1 -0
- package/dist/helpers/prompt-orchestrator.d.ts +12 -0
- package/dist/helpers/prompt-orchestrator.d.ts.map +1 -0
- package/dist/helpers/prompt-orchestrator.js +133 -0
- package/dist/helpers/prompt-orchestrator.js.map +1 -0
- package/dist/index.d.ts +17 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +22 -0
- package/dist/index.js.map +1 -0
- package/dist/loopman-agent-wrapper.d.ts +70 -0
- package/dist/loopman-agent-wrapper.d.ts.map +1 -0
- package/dist/loopman-agent-wrapper.js +157 -0
- package/dist/loopman-agent-wrapper.js.map +1 -0
- package/dist/loopman-middleware.d.ts +78 -0
- package/dist/loopman-middleware.d.ts.map +1 -0
- package/dist/loopman-middleware.js +367 -0
- package/dist/loopman-middleware.js.map +1 -0
- package/dist/mcp/loopman-mcp-client.d.ts +17 -0
- package/dist/mcp/loopman-mcp-client.d.ts.map +1 -0
- package/dist/mcp/loopman-mcp-client.js +76 -0
- package/dist/mcp/loopman-mcp-client.js.map +1 -0
- package/dist/mcp/tool-registry.d.ts +29 -0
- package/dist/mcp/tool-registry.d.ts.map +1 -0
- package/dist/mcp/tool-registry.js +143 -0
- package/dist/mcp/tool-registry.js.map +1 -0
- package/dist/services/index.d.ts +12 -0
- package/dist/services/index.d.ts.map +1 -0
- package/dist/services/index.js +9 -0
- package/dist/services/index.js.map +1 -0
- package/dist/services/logger.service.d.ts +107 -0
- package/dist/services/logger.service.d.ts.map +1 -0
- package/dist/services/logger.service.js +173 -0
- package/dist/services/logger.service.js.map +1 -0
- package/dist/services/loopman.service.d.ts +72 -0
- package/dist/services/loopman.service.d.ts.map +1 -0
- package/dist/services/loopman.service.js +271 -0
- package/dist/services/loopman.service.js.map +1 -0
- package/dist/services/polling.service.d.ts +136 -0
- package/dist/services/polling.service.d.ts.map +1 -0
- package/dist/services/polling.service.js +428 -0
- package/dist/services/polling.service.js.map +1 -0
- package/dist/types.d.ts +242 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +35 -0
- package/dist/types.js.map +1 -0
- package/package.json +58 -0
|
@@ -0,0 +1,367 @@
|
|
|
1
|
+
import { AIMessage, SystemMessage, ToolMessage, } from "@langchain/core/messages";
|
|
2
|
+
import { createMiddleware } from "langchain";
|
|
3
|
+
import { z } from "zod";
|
|
4
|
+
import { LoopmanService } from "./services/loopman.service";
|
|
5
|
+
/**
|
|
6
|
+
* Loopman middleware for LangChain v1.0
|
|
7
|
+
*
|
|
8
|
+
* Integrates Human-in-the-Loop validation via Loopman platform
|
|
9
|
+
* for tool call validation
|
|
10
|
+
*
|
|
11
|
+
* @example Basic Usage
|
|
12
|
+
* ```typescript
|
|
13
|
+
* loopmanMiddleware({
|
|
14
|
+
* apiKey: process.env.LOOPMAN_API_KEY!,
|
|
15
|
+
* workflowId: "email-workflow",
|
|
16
|
+
* interruptOn: {
|
|
17
|
+
* send_email: true, // Requires validation
|
|
18
|
+
* read_email: false // Auto-approved
|
|
19
|
+
* }
|
|
20
|
+
* })
|
|
21
|
+
* ```
|
|
22
|
+
*/
|
|
23
|
+
export function loopmanMiddleware(config) {
|
|
24
|
+
const { apiKey, workflowId, executionId = `exec-${Date.now()}-${Math.random().toString(36)}`, channelId, interruptOn = {}, timeout = 5 * 60 * 1000, // 5 minutes
|
|
25
|
+
pollingInterval = 5000, // 5 seconds
|
|
26
|
+
debug = false, } = config;
|
|
27
|
+
// Keep config reference to access dynamic parentTaskId
|
|
28
|
+
const configRef = config;
|
|
29
|
+
// Initialize Loopman service
|
|
30
|
+
const loopmanService = new LoopmanService({
|
|
31
|
+
apiKey,
|
|
32
|
+
workflowId,
|
|
33
|
+
executionId,
|
|
34
|
+
channelId,
|
|
35
|
+
timeout,
|
|
36
|
+
pollingInterval,
|
|
37
|
+
debug,
|
|
38
|
+
});
|
|
39
|
+
// Get logger directly from loopmanService
|
|
40
|
+
const logger = loopmanService.logger;
|
|
41
|
+
// Helper functions for logging
|
|
42
|
+
const log = (message, data) => logger.info(message, data);
|
|
43
|
+
const logError = (message, data) => logger.error(message, data);
|
|
44
|
+
const logWarn = (message, data) => logger.warn(message, data);
|
|
45
|
+
const logDebug = (message, data) => logger.debug(message, data);
|
|
46
|
+
/**
|
|
47
|
+
* Send task request to Loopman API and wait for human response
|
|
48
|
+
* Uses PollingService directly for maximum control and transparency
|
|
49
|
+
*/
|
|
50
|
+
const sendToolCallToLoopman = async (toolCall, aiMessageContent, userMessage) => {
|
|
51
|
+
log(`🔄 Sending decision request to Loopman for tool: ${toolCall.name}`, toolCall.args);
|
|
52
|
+
try {
|
|
53
|
+
// Business context: User's original request OR LLM's reasoning (prefer user)
|
|
54
|
+
let businessContext = userMessage || aiMessageContent || undefined;
|
|
55
|
+
let proposedDecision;
|
|
56
|
+
let decisionReasoning;
|
|
57
|
+
// If we have a parent task, fetch its context to enrich the tool validation
|
|
58
|
+
// Access parentTaskId dynamically from config reference
|
|
59
|
+
const parentTaskId = configRef.parentTaskId;
|
|
60
|
+
if (parentTaskId) {
|
|
61
|
+
try {
|
|
62
|
+
log(`🔗 Fetching parent task context from task: ${parentTaskId}`);
|
|
63
|
+
const parentTask = await loopmanService.getTask(parentTaskId);
|
|
64
|
+
if (parentTask != null) {
|
|
65
|
+
// Reuse business context from parent if not already provided
|
|
66
|
+
if (parentTask.businessContext) {
|
|
67
|
+
businessContext = parentTask.businessContext;
|
|
68
|
+
logDebug(`📋 Inherited businessContext from parent task`);
|
|
69
|
+
}
|
|
70
|
+
// Extract proposedDecision and decisionReasoning from parent task
|
|
71
|
+
if (parentTask.proposedDecision) {
|
|
72
|
+
proposedDecision = parentTask.proposedDecision;
|
|
73
|
+
logDebug(`📋 Inherited proposedDecision from parent task`);
|
|
74
|
+
}
|
|
75
|
+
if (parentTask.decisionReasoning) {
|
|
76
|
+
decisionReasoning = parentTask.decisionReasoning;
|
|
77
|
+
logDebug(`📋 Inherited decisionReasoning from parent task`);
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
catch (error) {
|
|
82
|
+
logWarn(`⚠️ Failed to fetch parent task ${parentTaskId}:`, error);
|
|
83
|
+
// Continue without parent context
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
// Step 1: Create task in Loopman for validation
|
|
87
|
+
const task = await loopmanService.createTaskForValidation(toolCall.name, toolCall.args, `Validation required for tool: ${toolCall.name}`, toolCall.id, // Use LangChain's unique tool_call_id
|
|
88
|
+
businessContext, // Business context (from parent or current)
|
|
89
|
+
parentTaskId, // Link to parent reflection task
|
|
90
|
+
proposedDecision, // From parent task
|
|
91
|
+
decisionReasoning // From parent task
|
|
92
|
+
);
|
|
93
|
+
// Set taskId in logger for subsequent logs
|
|
94
|
+
logger.setTaskId(task.id);
|
|
95
|
+
log(`📝 Task created with ID: ${task.id}`, {
|
|
96
|
+
status: task.status,
|
|
97
|
+
});
|
|
98
|
+
// Step 2: Poll directly with PollingService
|
|
99
|
+
const pollingOptions = loopmanService.getPollingOptions(task.id);
|
|
100
|
+
const pollingResult = await loopmanService.polling.waitForDecision(pollingOptions);
|
|
101
|
+
// Handle timeout or abort
|
|
102
|
+
if (pollingResult.status === "TIMEOUT") {
|
|
103
|
+
throw new Error(`Timeout: Task ${task.id} was not resolved within timeout`);
|
|
104
|
+
}
|
|
105
|
+
if (pollingResult.status === "ABORTED") {
|
|
106
|
+
throw new Error(`Polling aborted: Task ${task.id} polling was cancelled`);
|
|
107
|
+
}
|
|
108
|
+
// Get final task data
|
|
109
|
+
// If polling didn't return the full task, fetch it
|
|
110
|
+
const finalTask = pollingResult.data
|
|
111
|
+
? await loopmanService.getTask(task.id)
|
|
112
|
+
: await loopmanService.getTask(task.id);
|
|
113
|
+
log(`✅ Task resolved:`, {
|
|
114
|
+
id: finalTask.id,
|
|
115
|
+
status: finalTask.status,
|
|
116
|
+
metadata: finalTask.metadata,
|
|
117
|
+
});
|
|
118
|
+
return finalTask;
|
|
119
|
+
}
|
|
120
|
+
catch (error) {
|
|
121
|
+
logError(`❌ Failed to get decision from Loopman:`, error instanceof Error ? error.message : String(error));
|
|
122
|
+
throw error;
|
|
123
|
+
}
|
|
124
|
+
};
|
|
125
|
+
/**
|
|
126
|
+
* Process Tool Call Loopman decision and determine action
|
|
127
|
+
*
|
|
128
|
+
* @param task - The task response from Loopman API
|
|
129
|
+
* @param originalToolCall - The original tool call from the AI
|
|
130
|
+
* @returns Object containing:
|
|
131
|
+
* - revisedToolCall: The tool call to execute (modified or original) or null
|
|
132
|
+
* - toolMessage: Artificial ToolMessage for rejected tools or null
|
|
133
|
+
*/
|
|
134
|
+
const processToolCallLoopmanTask = (task, originalToolCall) => {
|
|
135
|
+
// Extract feedback from latest decision OR task metadata
|
|
136
|
+
let feedback;
|
|
137
|
+
// Priority 1: Get feedback from latest decision (human comment)
|
|
138
|
+
if (task.decisions && task.decisions.length > 0) {
|
|
139
|
+
const latestDecision = task.decisions[0]; // Already sorted by date desc
|
|
140
|
+
feedback = latestDecision.comment || undefined;
|
|
141
|
+
if (feedback) {
|
|
142
|
+
log(`📝 Found feedback from decision:`, feedback);
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
// Fallback: Get feedback from metadata (legacy system)
|
|
146
|
+
if (!feedback) {
|
|
147
|
+
feedback = task.metadata?.feedback || task.description;
|
|
148
|
+
}
|
|
149
|
+
// Extract modified data from metadata (fallback for manual edits)
|
|
150
|
+
const modifiedData = task.metadata?.modified_tool_args || task.metadata?.modifiedToolArgs;
|
|
151
|
+
log(`📋 Processing Loopman task:`, {
|
|
152
|
+
status: task.status,
|
|
153
|
+
toolName: originalToolCall.name,
|
|
154
|
+
hasFeedback: !!feedback,
|
|
155
|
+
hasModifiedData: !!modifiedData,
|
|
156
|
+
});
|
|
157
|
+
switch (task.status) {
|
|
158
|
+
case "APPROVED":
|
|
159
|
+
// ✅ Human approved - Execute tool with original arguments
|
|
160
|
+
log(`✅ Tool '${originalToolCall.name}' APPROVED - executing as-is`);
|
|
161
|
+
return {
|
|
162
|
+
revisedToolCall: originalToolCall,
|
|
163
|
+
toolMessage: null,
|
|
164
|
+
};
|
|
165
|
+
case "NEEDS_CHANGES":
|
|
166
|
+
// ✏️ Case 1: Human provided modified data manually (fallback)
|
|
167
|
+
if (modifiedData) {
|
|
168
|
+
log(`✏️ Tool '${originalToolCall.name}' NEEDS_CHANGES - executing with modified arguments:`, modifiedData);
|
|
169
|
+
return {
|
|
170
|
+
revisedToolCall: {
|
|
171
|
+
...originalToolCall,
|
|
172
|
+
args: modifiedData,
|
|
173
|
+
},
|
|
174
|
+
toolMessage: null,
|
|
175
|
+
};
|
|
176
|
+
}
|
|
177
|
+
// 💬 Case 2: Human provided feedback → ask LLM to auto-correct
|
|
178
|
+
if (feedback) {
|
|
179
|
+
log(`💬 Tool '${originalToolCall.name}' NEEDS_CHANGES - returning feedback to agent for auto-correction`);
|
|
180
|
+
// Return a tool message indicating the tool wasn't executed
|
|
181
|
+
// and the agent should try again with corrections
|
|
182
|
+
return {
|
|
183
|
+
revisedToolCall: null,
|
|
184
|
+
toolMessage: new ToolMessage({
|
|
185
|
+
content: `Tool execution was paused for human review. Human feedback: "${feedback}". Please generate a new corrected tool call based on this feedback.`,
|
|
186
|
+
name: originalToolCall.name,
|
|
187
|
+
tool_call_id: originalToolCall.id || `tool-${Date.now()}`,
|
|
188
|
+
}),
|
|
189
|
+
};
|
|
190
|
+
}
|
|
191
|
+
// ⚠️ Case 3: Neither feedback nor data → warning + execute original
|
|
192
|
+
logWarn(`⚠️ Tool '${originalToolCall.name}' marked NEEDS_CHANGES but no feedback/data provided, executing original`);
|
|
193
|
+
return {
|
|
194
|
+
revisedToolCall: originalToolCall,
|
|
195
|
+
toolMessage: null,
|
|
196
|
+
};
|
|
197
|
+
case "REJECTED":
|
|
198
|
+
// ❌ Human rejected - Cancel execution with feedback
|
|
199
|
+
log(`❌ Tool '${originalToolCall.name}' REJECTED - cancelling execution`);
|
|
200
|
+
const rejectedFeedback = feedback ||
|
|
201
|
+
`Tool call "${originalToolCall.name}" was rejected by human reviewer`;
|
|
202
|
+
return {
|
|
203
|
+
revisedToolCall: null,
|
|
204
|
+
toolMessage: new ToolMessage({
|
|
205
|
+
content: rejectedFeedback,
|
|
206
|
+
name: originalToolCall.name,
|
|
207
|
+
tool_call_id: originalToolCall.id || `tool-${Date.now()}`,
|
|
208
|
+
status: "error",
|
|
209
|
+
}),
|
|
210
|
+
};
|
|
211
|
+
case "PENDING":
|
|
212
|
+
// This should not happen as we poll until resolved
|
|
213
|
+
logWarn(`⚠️ Tool '${originalToolCall.name}' still PENDING after polling - treating as timeout`);
|
|
214
|
+
return {
|
|
215
|
+
revisedToolCall: null,
|
|
216
|
+
toolMessage: new ToolMessage({
|
|
217
|
+
content: `Tool call "${originalToolCall.name}" timed out waiting for human review`,
|
|
218
|
+
name: originalToolCall.name,
|
|
219
|
+
tool_call_id: originalToolCall.id || `tool-${Date.now()}`,
|
|
220
|
+
status: "error",
|
|
221
|
+
}),
|
|
222
|
+
};
|
|
223
|
+
default:
|
|
224
|
+
// Unknown status
|
|
225
|
+
throw new Error(`Unknown Loopman task status: ${task.status} for tool ${originalToolCall.name}`);
|
|
226
|
+
}
|
|
227
|
+
};
|
|
228
|
+
return createMiddleware({
|
|
229
|
+
name: "LoopmanMiddleware",
|
|
230
|
+
contextSchema: z.object({
|
|
231
|
+
interruptOn: z.record(z.boolean()).optional(),
|
|
232
|
+
}),
|
|
233
|
+
afterModel: {
|
|
234
|
+
hook: async (state, runtime) => {
|
|
235
|
+
const { messages } = state;
|
|
236
|
+
if (!messages.length)
|
|
237
|
+
return;
|
|
238
|
+
// Get last AI message
|
|
239
|
+
const lastMessage = [...messages]
|
|
240
|
+
.reverse()
|
|
241
|
+
.find((msg) => AIMessage.isInstance(msg));
|
|
242
|
+
if (!lastMessage)
|
|
243
|
+
return;
|
|
244
|
+
/**
|
|
245
|
+
* Check for tool calls validation
|
|
246
|
+
*/
|
|
247
|
+
if (!lastMessage.tool_calls?.length) {
|
|
248
|
+
log("No tool calls found");
|
|
249
|
+
return;
|
|
250
|
+
}
|
|
251
|
+
log(`Found ${lastMessage.tool_calls.length} tool calls`);
|
|
252
|
+
// Separate tools that need validation vs auto-approved
|
|
253
|
+
const interruptToolCalls = [];
|
|
254
|
+
const autoApprovedToolCalls = [];
|
|
255
|
+
for (const toolCall of lastMessage.tool_calls) {
|
|
256
|
+
logDebug(`Checking tool: "${toolCall.name}"`);
|
|
257
|
+
logDebug(`interruptOn config:`, interruptOn);
|
|
258
|
+
const shouldInterrupt = interruptOn[toolCall.name] ?? false;
|
|
259
|
+
logDebug(`Should interrupt? ${shouldInterrupt}`);
|
|
260
|
+
if (shouldInterrupt) {
|
|
261
|
+
logDebug(`Tool '${toolCall.name}' requires validation`);
|
|
262
|
+
interruptToolCalls.push(toolCall);
|
|
263
|
+
}
|
|
264
|
+
else {
|
|
265
|
+
logDebug(`Tool '${toolCall.name}' auto-approved`);
|
|
266
|
+
autoApprovedToolCalls.push(toolCall);
|
|
267
|
+
}
|
|
268
|
+
}
|
|
269
|
+
// If no tools need validation, continue normally
|
|
270
|
+
if (interruptToolCalls.length === 0) {
|
|
271
|
+
logDebug("No tools require validation");
|
|
272
|
+
return;
|
|
273
|
+
}
|
|
274
|
+
log(`Requesting validation for ${interruptToolCalls.length} tools`);
|
|
275
|
+
// Extract business context from messages
|
|
276
|
+
const aiMessageContent = typeof lastMessage.content === "string"
|
|
277
|
+
? lastMessage.content
|
|
278
|
+
: undefined;
|
|
279
|
+
// Find the last user message for context
|
|
280
|
+
const lastUserMessage = [...messages]
|
|
281
|
+
.reverse()
|
|
282
|
+
.find((msg) => msg._getType() === "human");
|
|
283
|
+
const userMessageContent = lastUserMessage && typeof lastUserMessage.content === "string"
|
|
284
|
+
? lastUserMessage.content
|
|
285
|
+
: undefined;
|
|
286
|
+
// Send each tool call to Loopman and wait for human validation
|
|
287
|
+
// Handle errors individually to allow graceful degradation
|
|
288
|
+
const taskResults = [];
|
|
289
|
+
for (const toolCall of interruptToolCalls) {
|
|
290
|
+
try {
|
|
291
|
+
const task = await sendToolCallToLoopman(toolCall, aiMessageContent, userMessageContent);
|
|
292
|
+
taskResults.push({ toolCall, task });
|
|
293
|
+
}
|
|
294
|
+
catch (error) {
|
|
295
|
+
// Store error for this specific tool call
|
|
296
|
+
logError(`Tool '${toolCall.name}' validation failed:`, error instanceof Error ? error.message : String(error));
|
|
297
|
+
taskResults.push({
|
|
298
|
+
toolCall,
|
|
299
|
+
error: error instanceof Error ? error : new Error(String(error)),
|
|
300
|
+
});
|
|
301
|
+
}
|
|
302
|
+
}
|
|
303
|
+
// Process tasks and handle rejections/errors
|
|
304
|
+
const artificialToolMessages = [];
|
|
305
|
+
const allToolCalls = [...autoApprovedToolCalls];
|
|
306
|
+
for (const result of taskResults) {
|
|
307
|
+
if (result.error) {
|
|
308
|
+
// Create error ToolMessage for failed validation (timeout, API error, etc.)
|
|
309
|
+
const errorMessage = result.error.message.includes("Timeout")
|
|
310
|
+
? `Tool call "${result.toolCall.name}" timed out waiting for human validation`
|
|
311
|
+
: `Tool call "${result.toolCall.name}" failed: ${result.error.message}`;
|
|
312
|
+
artificialToolMessages.push(new ToolMessage({
|
|
313
|
+
content: errorMessage,
|
|
314
|
+
name: result.toolCall.name,
|
|
315
|
+
tool_call_id: result.toolCall.id || `tool-${Date.now()}`,
|
|
316
|
+
status: "error",
|
|
317
|
+
}));
|
|
318
|
+
}
|
|
319
|
+
else if (result.task) {
|
|
320
|
+
// Process successful task
|
|
321
|
+
const { revisedToolCall, toolMessage } = processToolCallLoopmanTask(result.task, result.toolCall);
|
|
322
|
+
if (revisedToolCall) {
|
|
323
|
+
allToolCalls.push(revisedToolCall);
|
|
324
|
+
}
|
|
325
|
+
// Only add artificial tool messages for rejections/needs_changes
|
|
326
|
+
// For approvals/modifications, let the agent execute the tools normally
|
|
327
|
+
if (toolMessage) {
|
|
328
|
+
artificialToolMessages.push(toolMessage);
|
|
329
|
+
}
|
|
330
|
+
}
|
|
331
|
+
}
|
|
332
|
+
// If we have rejections/errors/feedback, inject artificial tool messages
|
|
333
|
+
if (artificialToolMessages.length > 0) {
|
|
334
|
+
log(`Injecting ${artificialToolMessages.length} rejection/error/feedback messages`);
|
|
335
|
+
// Create a new AI message with only approved/modified tool calls
|
|
336
|
+
const approvedToolCalls = allToolCalls.filter((tc) => !artificialToolMessages.some((msg) => msg.tool_call_id === tc.id));
|
|
337
|
+
if (approvedToolCalls.length > 0) {
|
|
338
|
+
// Some tools approved, some rejected/errored - create new message with approved ones
|
|
339
|
+
const newAIMessage = new AIMessage({
|
|
340
|
+
content: lastMessage.content,
|
|
341
|
+
tool_calls: approvedToolCalls,
|
|
342
|
+
});
|
|
343
|
+
return {
|
|
344
|
+
messages: [newAIMessage, ...artificialToolMessages],
|
|
345
|
+
};
|
|
346
|
+
}
|
|
347
|
+
else {
|
|
348
|
+
// All tools rejected/errored/need-changes - return error messages
|
|
349
|
+
// Add a system message to force agent to continue thinking
|
|
350
|
+
const systemMessage = new SystemMessage({
|
|
351
|
+
content: "The previous tool call was not executed. Please analyze the feedback above and generate a new corrected tool call.",
|
|
352
|
+
});
|
|
353
|
+
return {
|
|
354
|
+
messages: [...artificialToolMessages, systemMessage],
|
|
355
|
+
};
|
|
356
|
+
}
|
|
357
|
+
}
|
|
358
|
+
// All tools approved/modified - let the agent execute them normally
|
|
359
|
+
log(`All ${allToolCalls.length} tool calls approved, continuing normal execution`);
|
|
360
|
+
// Don't return any messages - let the agent continue its normal execution flow
|
|
361
|
+
// The tool calls will be executed and ToolMessages will be generated automatically
|
|
362
|
+
return;
|
|
363
|
+
},
|
|
364
|
+
},
|
|
365
|
+
});
|
|
366
|
+
}
|
|
367
|
+
//# sourceMappingURL=loopman-middleware.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"loopman-middleware.js","sourceRoot":"","sources":["../src/loopman-middleware.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
export interface LoopmanMcpClientConfig {
|
|
2
|
+
apiKey: string;
|
|
3
|
+
serverUrl?: string;
|
|
4
|
+
timeoutMs?: number;
|
|
5
|
+
}
|
|
6
|
+
export declare class LoopmanMcpClient {
|
|
7
|
+
private readonly config;
|
|
8
|
+
private client;
|
|
9
|
+
private connected;
|
|
10
|
+
constructor(config: LoopmanMcpClientConfig);
|
|
11
|
+
get isConnected(): boolean;
|
|
12
|
+
connect(): Promise<void>;
|
|
13
|
+
disconnect(): Promise<void>;
|
|
14
|
+
getTools(): Promise<any[]>;
|
|
15
|
+
private checkHealth;
|
|
16
|
+
}
|
|
17
|
+
//# sourceMappingURL=loopman-mcp-client.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"loopman-mcp-client.d.ts","sourceRoot":"","sources":["../../src/mcp/loopman-mcp-client.ts"],"names":[],"mappings":"AAEA,MAAM,WAAW,sBAAsB;IACrC,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,qBAAa,gBAAgB;IAC3B,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAmC;IAC1D,OAAO,CAAC,MAAM,CAAqC;IACnD,OAAO,CAAC,SAAS,CAAS;gBAEd,MAAM,EAAE,sBAAsB;IAQ1C,IAAI,WAAW,IAAI,OAAO,CAEzB;IAEK,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;IAyBxB,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;IAS3B,QAAQ,IAAI,OAAO,CAAC,GAAG,EAAE,CAAC;YAQlB,WAAW;CAgC1B"}
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import { MultiServerMCPClient } from "@langchain/mcp-adapters";
|
|
2
|
+
export class LoopmanMcpClient {
|
|
3
|
+
config;
|
|
4
|
+
client = null;
|
|
5
|
+
connected = false;
|
|
6
|
+
constructor(config) {
|
|
7
|
+
this.config = {
|
|
8
|
+
serverUrl: config.serverUrl ?? process.env.LOOPMAN_MCP_SERVER_URL ?? "https://mcp.loopman.ai",
|
|
9
|
+
timeoutMs: config.timeoutMs ?? 30_000,
|
|
10
|
+
apiKey: config.apiKey,
|
|
11
|
+
};
|
|
12
|
+
}
|
|
13
|
+
get isConnected() {
|
|
14
|
+
return this.connected;
|
|
15
|
+
}
|
|
16
|
+
async connect() {
|
|
17
|
+
if (this.connected) {
|
|
18
|
+
return;
|
|
19
|
+
}
|
|
20
|
+
await this.checkHealth();
|
|
21
|
+
if (!this.client) {
|
|
22
|
+
this.client = new MultiServerMCPClient({
|
|
23
|
+
loopman: {
|
|
24
|
+
transport: "sse",
|
|
25
|
+
url: `${this.config.serverUrl}/mcp/sse`,
|
|
26
|
+
headers: {
|
|
27
|
+
Authorization: `Bearer ${this.config.apiKey}`,
|
|
28
|
+
"Content-Type": "application/json",
|
|
29
|
+
},
|
|
30
|
+
},
|
|
31
|
+
});
|
|
32
|
+
}
|
|
33
|
+
// Initialize the SSE connection
|
|
34
|
+
await this.client.initializeConnections();
|
|
35
|
+
this.connected = true;
|
|
36
|
+
}
|
|
37
|
+
async disconnect() {
|
|
38
|
+
if (!this.client || !this.connected) {
|
|
39
|
+
return;
|
|
40
|
+
}
|
|
41
|
+
await this.client.close();
|
|
42
|
+
this.connected = false;
|
|
43
|
+
}
|
|
44
|
+
async getTools() {
|
|
45
|
+
if (!this.client || !this.connected) {
|
|
46
|
+
throw new Error("Loopman MCP client is not connected");
|
|
47
|
+
}
|
|
48
|
+
return this.client.getTools();
|
|
49
|
+
}
|
|
50
|
+
async checkHealth() {
|
|
51
|
+
const controller = new AbortController();
|
|
52
|
+
const timeout = setTimeout(() => controller.abort(), this.config.timeoutMs);
|
|
53
|
+
try {
|
|
54
|
+
const response = await fetch(`${this.config.serverUrl}/mcp/health`, {
|
|
55
|
+
headers: {
|
|
56
|
+
Authorization: `Bearer ${this.config.apiKey}`,
|
|
57
|
+
},
|
|
58
|
+
signal: controller.signal,
|
|
59
|
+
});
|
|
60
|
+
if (!response.ok) {
|
|
61
|
+
throw new Error(`Health check failed with status ${response.status}`);
|
|
62
|
+
}
|
|
63
|
+
const data = await response.json();
|
|
64
|
+
if (!data || (data.status !== "ok" && data.status !== "healthy")) {
|
|
65
|
+
throw new Error("MCP server health check did not return a healthy status");
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
catch (error) {
|
|
69
|
+
throw new Error(`Unable to reach Loopman MCP server at ${this.config.serverUrl}: ${error instanceof Error ? error.message : String(error)}`);
|
|
70
|
+
}
|
|
71
|
+
finally {
|
|
72
|
+
clearTimeout(timeout);
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
//# sourceMappingURL=loopman-mcp-client.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"loopman-mcp-client.js","sourceRoot":"","sources":["../../src/mcp/loopman-mcp-client.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { DynamicStructuredTool } from "@langchain/core/tools";
|
|
2
|
+
import { z } from "zod";
|
|
3
|
+
export interface LoopmanToolRegistryConfig {
|
|
4
|
+
workflowId: string;
|
|
5
|
+
executionId: string;
|
|
6
|
+
category?: string;
|
|
7
|
+
channelId?: string;
|
|
8
|
+
debug?: boolean;
|
|
9
|
+
}
|
|
10
|
+
type McpTool = {
|
|
11
|
+
name: string;
|
|
12
|
+
description?: string;
|
|
13
|
+
schema?: z.ZodTypeAny;
|
|
14
|
+
inputSchema?: z.ZodTypeAny;
|
|
15
|
+
func: (args: Record<string, unknown>) => Promise<unknown>;
|
|
16
|
+
};
|
|
17
|
+
export declare class LoopmanToolRegistry {
|
|
18
|
+
private readonly config;
|
|
19
|
+
constructor(config: LoopmanToolRegistryConfig);
|
|
20
|
+
toDynamicTools(mcpTools: McpTool[]): DynamicStructuredTool[];
|
|
21
|
+
private createTool;
|
|
22
|
+
private resolveSchema;
|
|
23
|
+
private prepareArgs;
|
|
24
|
+
private buildDescription;
|
|
25
|
+
private describeSchema;
|
|
26
|
+
private isZodSchema;
|
|
27
|
+
}
|
|
28
|
+
export {};
|
|
29
|
+
//# sourceMappingURL=tool-registry.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tool-registry.d.ts","sourceRoot":"","sources":["../../src/mcp/tool-registry.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,qBAAqB,EAAE,MAAM,uBAAuB,CAAC;AAC9D,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,MAAM,WAAW,yBAAyB;IACxC,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE,OAAO,CAAC;CACjB;AAED,KAAK,OAAO,GAAG;IACb,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,MAAM,CAAC,EAAE,CAAC,CAAC,UAAU,CAAC;IACtB,WAAW,CAAC,EAAE,CAAC,CAAC,UAAU,CAAC;IAC3B,IAAI,EAAE,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;CAC3D,CAAC;AAEF,qBAAa,mBAAmB;IAClB,OAAO,CAAC,QAAQ,CAAC,MAAM;gBAAN,MAAM,EAAE,yBAAyB;IAE9D,cAAc,CAAC,QAAQ,EAAE,OAAO,EAAE,GAAG,qBAAqB,EAAE;IAI5D,OAAO,CAAC,UAAU;IA6BlB,OAAO,CAAC,aAAa;IAgErB,OAAO,CAAC,WAAW;IAsCnB,OAAO,CAAC,gBAAgB;IAMxB,OAAO,CAAC,cAAc;IA+BtB,OAAO,CAAC,WAAW;CAKpB"}
|