@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.
Files changed (55) hide show
  1. package/LICENSE +374 -0
  2. package/README.md +594 -0
  3. package/dist/agents/loopman-agent.d.ts +29 -0
  4. package/dist/agents/loopman-agent.d.ts.map +1 -0
  5. package/dist/agents/loopman-agent.js +441 -0
  6. package/dist/agents/loopman-agent.js.map +1 -0
  7. package/dist/client/loopman-api.d.ts +123 -0
  8. package/dist/client/loopman-api.d.ts.map +1 -0
  9. package/dist/client/loopman-api.js +407 -0
  10. package/dist/client/loopman-api.js.map +1 -0
  11. package/dist/helpers/prompt-orchestrator.d.ts +12 -0
  12. package/dist/helpers/prompt-orchestrator.d.ts.map +1 -0
  13. package/dist/helpers/prompt-orchestrator.js +133 -0
  14. package/dist/helpers/prompt-orchestrator.js.map +1 -0
  15. package/dist/index.d.ts +17 -0
  16. package/dist/index.d.ts.map +1 -0
  17. package/dist/index.js +22 -0
  18. package/dist/index.js.map +1 -0
  19. package/dist/loopman-agent-wrapper.d.ts +70 -0
  20. package/dist/loopman-agent-wrapper.d.ts.map +1 -0
  21. package/dist/loopman-agent-wrapper.js +157 -0
  22. package/dist/loopman-agent-wrapper.js.map +1 -0
  23. package/dist/loopman-middleware.d.ts +78 -0
  24. package/dist/loopman-middleware.d.ts.map +1 -0
  25. package/dist/loopman-middleware.js +367 -0
  26. package/dist/loopman-middleware.js.map +1 -0
  27. package/dist/mcp/loopman-mcp-client.d.ts +17 -0
  28. package/dist/mcp/loopman-mcp-client.d.ts.map +1 -0
  29. package/dist/mcp/loopman-mcp-client.js +76 -0
  30. package/dist/mcp/loopman-mcp-client.js.map +1 -0
  31. package/dist/mcp/tool-registry.d.ts +29 -0
  32. package/dist/mcp/tool-registry.d.ts.map +1 -0
  33. package/dist/mcp/tool-registry.js +143 -0
  34. package/dist/mcp/tool-registry.js.map +1 -0
  35. package/dist/services/index.d.ts +12 -0
  36. package/dist/services/index.d.ts.map +1 -0
  37. package/dist/services/index.js +9 -0
  38. package/dist/services/index.js.map +1 -0
  39. package/dist/services/logger.service.d.ts +107 -0
  40. package/dist/services/logger.service.d.ts.map +1 -0
  41. package/dist/services/logger.service.js +173 -0
  42. package/dist/services/logger.service.js.map +1 -0
  43. package/dist/services/loopman.service.d.ts +72 -0
  44. package/dist/services/loopman.service.d.ts.map +1 -0
  45. package/dist/services/loopman.service.js +271 -0
  46. package/dist/services/loopman.service.js.map +1 -0
  47. package/dist/services/polling.service.d.ts +136 -0
  48. package/dist/services/polling.service.d.ts.map +1 -0
  49. package/dist/services/polling.service.js +428 -0
  50. package/dist/services/polling.service.js.map +1 -0
  51. package/dist/types.d.ts +242 -0
  52. package/dist/types.d.ts.map +1 -0
  53. package/dist/types.js +35 -0
  54. package/dist/types.js.map +1 -0
  55. 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"}