@loopman/langchain-sdk 1.12.1 ā 1.12.2
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/README.md
CHANGED
|
@@ -1,65 +1,101 @@
|
|
|
1
|
-
# Loopman SDK
|
|
1
|
+
# Loopman LangChain SDK
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Official TypeScript SDK for integrating Human-in-the-Loop (HITL) validation into LangChain AI agents via the Loopman platform.
|
|
4
4
|
|
|
5
5
|
## š Table of Contents
|
|
6
6
|
|
|
7
7
|
- [Overview](#overview)
|
|
8
|
+
- [What is Loopman?](#what-is-loopman)
|
|
8
9
|
- [Features](#features)
|
|
9
10
|
- [Prerequisites](#prerequisites)
|
|
10
11
|
- [Installation](#installation)
|
|
11
12
|
- [Quick Start](#quick-start)
|
|
12
13
|
- [Examples](#examples)
|
|
13
|
-
- [
|
|
14
|
+
- [LangGraph Integration](#langgraph-integration)
|
|
14
15
|
- [Debugging](#debugging)
|
|
15
16
|
- [Project Structure](#project-structure)
|
|
16
17
|
- [API Reference](#api-reference)
|
|
17
18
|
- [Development](#development)
|
|
19
|
+
- [Related Resources](#related-resources)
|
|
18
20
|
- [License](#license)
|
|
19
21
|
|
|
20
22
|
---
|
|
21
23
|
|
|
22
24
|
## šÆ Overview
|
|
23
25
|
|
|
24
|
-
|
|
26
|
+
The Loopman LangChain SDK enables you to add human validation and oversight to your AI agents built with LangChain v1.0+. It provides seamless integration with the Loopman platform, allowing humans to approve, modify, or reject AI decisions in real-time through a modern mobile and web interface.
|
|
25
27
|
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
28
|
+
---
|
|
29
|
+
|
|
30
|
+
## š¤ What is Loopman?
|
|
31
|
+
|
|
32
|
+
**Loopman** is a Human-in-the-Loop platform that bridges AI agent orchestrators (LangChain, n8n, Zapier, Make) with human users for real-time validation, correction, or rejection of AI decisions.
|
|
33
|
+
|
|
34
|
+
**Key capabilities:**
|
|
29
35
|
|
|
30
|
-
|
|
36
|
+
- š± Mobile-first interface for rapid decision-making on-the-go
|
|
37
|
+
- š» Web dashboard for detailed review and oversight
|
|
38
|
+
- š Real-time push notifications when AI agents need approval
|
|
39
|
+
- š **Feedback loop**: Humans can reject decisions with feedback, enabling agents to learn and auto-correct
|
|
40
|
+
- š Decision history and audit trails
|
|
41
|
+
- šÆ Context-aware guidelines for consistent decision-making
|
|
42
|
+
|
|
43
|
+
**Use cases:** Email approval workflows, financial transaction validation, content moderation, data modification approval, critical operation oversight, compliance checkpoints.
|
|
31
44
|
|
|
32
45
|
---
|
|
33
46
|
|
|
34
47
|
## ⨠Features
|
|
35
48
|
|
|
49
|
+
### š”ļø Human-in-the-Loop Validation
|
|
50
|
+
|
|
51
|
+
- ā
**Transparent Integration**: Middleware handles validation automatically
|
|
52
|
+
- ā
**Selective Interruption**: Configure which tools require approval
|
|
53
|
+
- ā
**Multiple Decision Types**: Approve, Edit with modifications, or Reject with feedback
|
|
54
|
+
- ā
**Automatic Polling**: Real-time decision retrieval with configurable intervals
|
|
55
|
+
- ā
**Timeout Handling**: Built-in timeout and retry logic
|
|
56
|
+
- ā
**Context Enrichment**: Automatic guidelines and decision history integration
|
|
57
|
+
|
|
58
|
+
### š Feedback Loop - Learn from Human Decisions
|
|
59
|
+
|
|
60
|
+
The **feedback loop** is a key feature that enables continuous improvement of your AI agents:
|
|
61
|
+
|
|
62
|
+
- ā
**Human Rejection with Feedback**: When humans reject a decision, they can provide detailed feedback explaining why
|
|
63
|
+
- ā
**Automatic Agent Retry**: The agent receives the feedback and automatically retries with corrections
|
|
64
|
+
- ā
**Context Learning**: Feedback is stored in decision history and injected into future agent prompts
|
|
65
|
+
- ā
**Iterative Refinement**: Agents learn from past mistakes and improve over time
|
|
66
|
+
- ā
**Workflow Routing**: LangGraph conditional edges automatically route to retry logic on `NEEDS_CHANGES` status
|
|
67
|
+
|
|
68
|
+
**Example workflow:**
|
|
69
|
+
|
|
70
|
+
1. Agent proposes to send an email with incorrect tone
|
|
71
|
+
2. Human rejects with feedback: "Use a more professional tone"
|
|
72
|
+
3. Agent receives feedback and retries with corrected tone
|
|
73
|
+
4. Human approves the refined version
|
|
74
|
+
5. Future similar tasks benefit from this learned context
|
|
75
|
+
|
|
76
|
+
### š LangGraph Support
|
|
77
|
+
|
|
78
|
+
- ā
**Validation Nodes**: Reusable nodes for human approval workflows
|
|
79
|
+
- ā
**Conditional Routing**: Route based on human decisions (approve/reject/retry)
|
|
80
|
+
- ā
**Context Loading**: Automatic guidelines and decision history retrieval
|
|
81
|
+
- ā
**State Management**: Full integration with LangGraph state
|
|
82
|
+
- ā
**Helper Functions**: `enrichSystemPrompt()` for context injection
|
|
83
|
+
|
|
36
84
|
### š¤ Agent Capabilities
|
|
37
85
|
|
|
86
|
+
- ā
**High-Level Agent API**: `createLoopmanAgent()` for quick setup
|
|
38
87
|
- ā
**Tool Calling**: Dynamic tool execution with Zod validation
|
|
39
88
|
- ā
**Conversational Memory**: Stateful conversations with checkpointers
|
|
40
|
-
- ā
**
|
|
41
|
-
- ā
**
|
|
42
|
-
|
|
43
|
-
### š”ļø Human-in-the-Loop
|
|
44
|
-
|
|
45
|
-
- ā
**Native HITL Middleware**: LangChain's `humanInTheLoopMiddleware`
|
|
46
|
-
- ā
**Custom Loopman Middleware**: Platform-specific integration
|
|
47
|
-
- ā
**LangGraph Integration**: Reusable validation nodes with conditional routing
|
|
48
|
-
- ā
**Full State Sharing**: Send complete agent state to human reviewers
|
|
49
|
-
- ā
**Business Context**: Define context, proposed decisions, and reasoning
|
|
50
|
-
- ā
**Context Enrichment**: Automatic guidelines and decision history integration
|
|
51
|
-
- ā
**Helper Functions**: `enrichSystemPrompt()` for simplified agent integration
|
|
52
|
-
- ā
**Decision Types**: Approve, Edit, Reject workflows
|
|
53
|
-
- ā
**Selective Interruption**: Per-tool configuration
|
|
54
|
-
- ā
**Double Validation Layer**: Global MCP validation + tool-specific validation
|
|
55
|
-
- ā
**Flexible Execution Modes**: Auto-execution or manual control after approval
|
|
89
|
+
- ā
**MCP Integration**: Model Context Protocol support for advanced workflows
|
|
90
|
+
- ā
**Double Validation Layer**: Global + tool-specific validation
|
|
56
91
|
|
|
57
92
|
### š§ Developer Experience
|
|
58
93
|
|
|
59
|
-
- ā
**TypeScript**: Full type safety with
|
|
94
|
+
- ā
**TypeScript**: Full type safety with comprehensive types
|
|
95
|
+
- ā
**Multiple Integration Patterns**: Middleware, Agent API, LangGraph nodes
|
|
60
96
|
- ā
**Debugging**: VSCode launch configurations
|
|
61
|
-
- ā
**Examples**:
|
|
62
|
-
- ā
**Documentation**: Inline comments and guides
|
|
97
|
+
- ā
**Real-World Examples**: Production-ready code samples
|
|
98
|
+
- ā
**Comprehensive Documentation**: Inline comments and guides
|
|
63
99
|
|
|
64
100
|
---
|
|
65
101
|
|
|
@@ -130,46 +166,29 @@ const result = await agent.invoke(
|
|
|
130
166
|
);
|
|
131
167
|
```
|
|
132
168
|
|
|
133
|
-
###
|
|
134
|
-
|
|
135
|
-
```typescript
|
|
136
|
-
import { humanInTheLoopMiddleware } from "langchain";
|
|
137
|
-
|
|
138
|
-
const agent = createAgent({
|
|
139
|
-
model: "openai:gpt-4o-mini",
|
|
140
|
-
tools: [sendEmail],
|
|
141
|
-
middleware: [
|
|
142
|
-
humanInTheLoopMiddleware({
|
|
143
|
-
interruptOn: {
|
|
144
|
-
send_email: {
|
|
145
|
-
allowedDecisions: ["approve", "edit", "reject"],
|
|
146
|
-
description: "ā ļø Email requires approval",
|
|
147
|
-
},
|
|
148
|
-
},
|
|
149
|
-
}),
|
|
150
|
-
],
|
|
151
|
-
checkpointer: new MemorySaver(),
|
|
152
|
-
});
|
|
153
|
-
```
|
|
154
|
-
|
|
155
|
-
### Loopman Platform Integration
|
|
169
|
+
### Middleware Integration (Standard HITL Process)
|
|
156
170
|
|
|
157
171
|
```typescript
|
|
158
|
-
import {
|
|
172
|
+
import { createAgent } from "langchain";
|
|
173
|
+
import { loopmanMiddleware } from "@loopman/langchain-sdk";
|
|
174
|
+
import { MemorySaver } from "@langchain/langgraph";
|
|
159
175
|
|
|
176
|
+
// Create agent with Loopman middleware
|
|
160
177
|
const agent = createAgent({
|
|
161
178
|
model: "openai:gpt-4o-mini",
|
|
162
|
-
tools: [sendEmail],
|
|
179
|
+
tools: [sendEmail, readEmail],
|
|
163
180
|
middleware: [
|
|
164
181
|
loopmanMiddleware({
|
|
165
182
|
apiKey: process.env.LOOPMAN_API_KEY!,
|
|
166
183
|
workflowId: "email-workflow",
|
|
184
|
+
mode: "tool-validation", // or "prompt-enhancement" or "full"
|
|
167
185
|
interruptOn: {
|
|
168
186
|
send_email: true, // Requires validation
|
|
169
187
|
read_email: false, // Auto-approved
|
|
170
188
|
},
|
|
189
|
+
timeout: 5 * 60 * 1000, // 5 minutes
|
|
171
190
|
pollingInterval: 5000, // Poll every 5 seconds
|
|
172
|
-
|
|
191
|
+
debug: true,
|
|
173
192
|
}),
|
|
174
193
|
],
|
|
175
194
|
checkpointer: new MemorySaver(),
|
|
@@ -185,49 +204,157 @@ const result = await agent.invoke(
|
|
|
185
204
|
// ā
Middleware handles HITL transparently
|
|
186
205
|
```
|
|
187
206
|
|
|
188
|
-
###
|
|
207
|
+
### Loopman Agent (Complete Solution - Ready to Use)
|
|
208
|
+
|
|
209
|
+
**What's the difference with Middleware?**
|
|
210
|
+
|
|
211
|
+
The **Middleware** requires you to build and configure your own agent, then add validation on top.
|
|
212
|
+
|
|
213
|
+
The **Loopman Agent** is a **ready-to-use agent** that includes everything:
|
|
214
|
+
|
|
215
|
+
- ā
Pre-built agent with validation already integrated
|
|
216
|
+
- ā
Automatic loading of guidelines and past decisions (feedback loop)
|
|
217
|
+
- ā
Simple API: just call `processWithHumanValidation()`
|
|
218
|
+
- ā
No manual configuration needed
|
|
219
|
+
|
|
220
|
+
**Perfect for:** Quick start, prototyping, or when you want a complete solution out-of-the-box.
|
|
221
|
+
|
|
222
|
+
```typescript
|
|
223
|
+
import { createLoopmanAgent } from "@loopman/langchain-sdk";
|
|
224
|
+
|
|
225
|
+
const agent = createLoopmanAgent({
|
|
226
|
+
apiKey: process.env.LOOPMAN_API_KEY!,
|
|
227
|
+
workflowId: "email-workflow",
|
|
228
|
+
model: "openai:gpt-4o-mini",
|
|
229
|
+
systemPrompt: "You are a helpful email assistant",
|
|
230
|
+
additionalTools: [sendEmail, readEmail],
|
|
231
|
+
requireApprovalForTools: ["send_email"], // Only email sending requires approval
|
|
232
|
+
debug: true,
|
|
233
|
+
});
|
|
234
|
+
|
|
235
|
+
// Usage - Simple and transparent!
|
|
236
|
+
const result = await agent.processWithHumanValidation({
|
|
237
|
+
input: "Send email to alice@example.com about the meeting",
|
|
238
|
+
});
|
|
239
|
+
// ā
Agent automatically handles validation via Loopman platform
|
|
240
|
+
```
|
|
241
|
+
|
|
242
|
+
### LangGraph Integration (Recommended)
|
|
189
243
|
|
|
190
244
|
```typescript
|
|
191
245
|
import {
|
|
192
246
|
LoopmanGraphState,
|
|
193
247
|
createLoopmanContextNode,
|
|
248
|
+
createLoopmanValidationNode,
|
|
249
|
+
createLoopmanConditionalEdge,
|
|
194
250
|
enrichSystemPrompt,
|
|
195
|
-
} from "loopman
|
|
196
|
-
import { StateGraph } from "@langchain/langgraph";
|
|
251
|
+
} from "@loopman/langchain-sdk";
|
|
252
|
+
import { StateGraph, START, END } from "@langchain/langgraph";
|
|
253
|
+
import { ChatOpenAI } from "@langchain/openai";
|
|
197
254
|
|
|
198
255
|
// 1. Create context node to load guidelines and decision history
|
|
199
256
|
const contextNode = createLoopmanContextNode({
|
|
200
257
|
apiKey: process.env.LOOPMAN_API_KEY!,
|
|
201
258
|
workflowId: "my-workflow",
|
|
202
259
|
category: "email",
|
|
260
|
+
debug: true,
|
|
203
261
|
});
|
|
204
262
|
|
|
205
|
-
// 2.
|
|
263
|
+
// 2. Create validation node for human approval
|
|
264
|
+
const validationNode = createLoopmanValidationNode({
|
|
265
|
+
apiKey: process.env.LOOPMAN_API_KEY!,
|
|
266
|
+
workflowId: "my-workflow",
|
|
267
|
+
debug: true,
|
|
268
|
+
});
|
|
269
|
+
|
|
270
|
+
// 3. Agent node with context-enriched prompts
|
|
206
271
|
async function agentNode(state: typeof LoopmanGraphState.State) {
|
|
207
272
|
const { messages, guidelines, decisionContext } = state;
|
|
208
273
|
|
|
209
274
|
// ⨠Automatically enrich system prompt with Loopman context
|
|
210
|
-
const systemPrompt = enrichSystemPrompt(
|
|
211
|
-
|
|
212
|
-
decisionContext,
|
|
213
|
-
|
|
275
|
+
const systemPrompt = enrichSystemPrompt(
|
|
276
|
+
"You are a helpful email assistant.",
|
|
277
|
+
{ guidelines, decisionContext },
|
|
278
|
+
{ maxDecisions: 3 } // Show last 3 decisions
|
|
279
|
+
);
|
|
214
280
|
|
|
215
|
-
const
|
|
281
|
+
const model = new ChatOpenAI({ model: "gpt-4o-mini" });
|
|
282
|
+
const modelWithTools = model.bindTools([sendEmail]);
|
|
283
|
+
|
|
284
|
+
const messagesWithContext = [
|
|
216
285
|
{ role: "system", content: systemPrompt },
|
|
217
286
|
...messages,
|
|
218
|
-
]
|
|
287
|
+
];
|
|
288
|
+
|
|
289
|
+
const response = await modelWithTools.invoke(messagesWithContext);
|
|
290
|
+
|
|
291
|
+
return {
|
|
292
|
+
messages: [response],
|
|
293
|
+
requiresValidation: response.tool_calls && response.tool_calls.length > 0,
|
|
294
|
+
};
|
|
295
|
+
}
|
|
296
|
+
|
|
297
|
+
// 4. Tool execution node
|
|
298
|
+
async function toolNode(state: typeof LoopmanGraphState.State) {
|
|
299
|
+
const { messages } = state;
|
|
300
|
+
const lastMessage = messages[messages.length - 1];
|
|
219
301
|
|
|
220
|
-
|
|
302
|
+
if (!lastMessage.tool_calls || lastMessage.tool_calls.length === 0) {
|
|
303
|
+
return {};
|
|
304
|
+
}
|
|
305
|
+
|
|
306
|
+
const toolCall = lastMessage.tool_calls[0];
|
|
307
|
+
const result = await sendEmail.invoke(toolCall.args);
|
|
308
|
+
|
|
309
|
+
return {
|
|
310
|
+
messages: [
|
|
311
|
+
new ToolMessage({
|
|
312
|
+
content: typeof result === "string" ? result : JSON.stringify(result),
|
|
313
|
+
tool_call_id: toolCall.id,
|
|
314
|
+
}),
|
|
315
|
+
],
|
|
316
|
+
requiresValidation: false,
|
|
317
|
+
};
|
|
221
318
|
}
|
|
222
319
|
|
|
223
|
-
//
|
|
320
|
+
// 5. Build workflow with validation and conditional routing
|
|
224
321
|
const workflow = new StateGraph(LoopmanGraphState)
|
|
225
322
|
.addNode("load_context", contextNode)
|
|
226
323
|
.addNode("agent", agentNode)
|
|
324
|
+
.addNode("loopman_validation", validationNode)
|
|
325
|
+
.addNode("tools", toolNode)
|
|
326
|
+
|
|
227
327
|
.addEdge(START, "load_context")
|
|
228
|
-
.addEdge("load_context", "agent")
|
|
328
|
+
.addEdge("load_context", "agent")
|
|
329
|
+
.addEdge("agent", "loopman_validation")
|
|
330
|
+
.addConditionalEdges(
|
|
331
|
+
"loopman_validation",
|
|
332
|
+
createLoopmanConditionalEdge({ debug: true }),
|
|
333
|
+
{
|
|
334
|
+
execute: "tools", // APPROVED ā execute tool
|
|
335
|
+
rejected: END, // REJECTED ā end workflow
|
|
336
|
+
retry: "agent", // NEEDS_CHANGES with feedback ā retry agent (FEEDBACK LOOP!)
|
|
337
|
+
timeout: END, // TIMEOUT ā end workflow
|
|
338
|
+
error: END, // ERROR ā end workflow
|
|
339
|
+
}
|
|
340
|
+
)
|
|
341
|
+
.addEdge("tools", END);
|
|
342
|
+
|
|
343
|
+
const app = workflow.compile({ checkpointer: new MemorySaver() });
|
|
229
344
|
```
|
|
230
345
|
|
|
346
|
+
**š Feedback Loop in Action:**
|
|
347
|
+
|
|
348
|
+
When a human rejects a decision with status `NEEDS_CHANGES`:
|
|
349
|
+
|
|
350
|
+
1. The validation node stores the human's feedback in `decisionContext`
|
|
351
|
+
2. The conditional edge routes to `retry: "agent"` instead of ending
|
|
352
|
+
3. The agent node receives the feedback via `enrichSystemPrompt()`
|
|
353
|
+
4. The agent corrects its decision based on human feedback
|
|
354
|
+
5. The workflow loops back to validation until approved
|
|
355
|
+
|
|
356
|
+
This creates a **continuous learning cycle** where agents improve through human guidance.
|
|
357
|
+
|
|
231
358
|
---
|
|
232
359
|
|
|
233
360
|
## š Examples
|
|
@@ -240,7 +367,6 @@ Comprehensive examples are organized in the `examples/` directory by complexity
|
|
|
240
367
|
|
|
241
368
|
- `01-simple-agent.ts` - Basic agent with tools and memory
|
|
242
369
|
- `02-memory-and-context.ts` - Conversational memory deep dive
|
|
243
|
-
- `03-langchain-native-hitl.ts` - LangChain's native HITL middleware
|
|
244
370
|
|
|
245
371
|
**2. Loopman Integration** (`examples/2-loopman-integration/`)
|
|
246
372
|
|
|
@@ -270,7 +396,7 @@ Comprehensive examples are organized in the `examples/` directory by complexity
|
|
|
270
396
|
```bash
|
|
271
397
|
# Basics
|
|
272
398
|
npx tsx examples/1-basics/01-simple-agent.ts
|
|
273
|
-
npx tsx examples/1-basics/
|
|
399
|
+
npx tsx examples/1-basics/02-memory-and-context.ts
|
|
274
400
|
|
|
275
401
|
# Loopman Integration
|
|
276
402
|
npx tsx examples/2-loopman-integration/01-middleware-basic.ts
|
|
@@ -290,112 +416,39 @@ npm run example:langgraph-full-state
|
|
|
290
416
|
|
|
291
417
|
See [Examples README](./examples/README.md) for detailed documentation and learning paths.
|
|
292
418
|
|
|
293
|
-
**New:**
|
|
294
|
-
- Check out the [LangGraph Integration Guide](./docs/LANGGRAPH_INTEGRATION.md) for building stateful workflows with Loopman validation nodes
|
|
295
|
-
- See [Full State Integration Guide](./docs/LANGGRAPH_FULL_STATE.md) for sharing complete agent state with human reviewers
|
|
296
|
-
|
|
297
419
|
---
|
|
298
420
|
|
|
299
|
-
|
|
421
|
+
## š LangGraph Integration
|
|
300
422
|
|
|
301
|
-
|
|
302
|
-
- **Automatic polling**: Middleware polls for decisions
|
|
303
|
-
- **Timeout handling**: Built-in timeout and retry logic
|
|
304
|
-
- **Fallback mechanism**: Auto-approval on API errors
|
|
305
|
-
- **Clean code**: Simple invoke() calls, HITL happens behind the scenes
|
|
306
|
-
- Debug logging for development
|
|
423
|
+
The SDK provides complete LangGraph support with reusable nodes for building stateful validation workflows.
|
|
307
424
|
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
## š Loopman Middleware
|
|
311
|
-
|
|
312
|
-
Custom middleware for integrating with the Loopman Human-in-the-Loop platform.
|
|
313
|
-
|
|
314
|
-
### Key Feature: Transparent Validation
|
|
315
|
-
|
|
316
|
-
**The middleware handles everything automatically!** No need to manually check for interruptions or poll for decisions.
|
|
317
|
-
|
|
318
|
-
```typescript
|
|
319
|
-
// Just invoke the agent - HITL happens transparently!
|
|
320
|
-
const result = await agent.invoke(
|
|
321
|
-
{
|
|
322
|
-
messages: [{ role: "user", content: "Send email to alice" }],
|
|
323
|
-
},
|
|
324
|
-
config
|
|
325
|
-
);
|
|
326
|
-
// ā
Decision already validated by human (if required)
|
|
327
|
-
```
|
|
425
|
+
### Key Components
|
|
328
426
|
|
|
329
|
-
|
|
427
|
+
1. **Context Node** (`createLoopmanContextNode`): Loads guidelines and decision history
|
|
428
|
+
2. **Validation Node** (`createLoopmanValidationNode`): Sends actions for human approval and polls for decisions
|
|
429
|
+
3. **Conditional Edge** (`createLoopmanConditionalEdge`): Routes workflow based on human decisions
|
|
430
|
+
4. **Helper Functions** (`enrichSystemPrompt`): Injects context into agent prompts
|
|
330
431
|
|
|
331
|
-
|
|
332
|
-
import { loopmanMiddleware } from "./src/loopman-middleware";
|
|
432
|
+
### Complete Workflow Example
|
|
333
433
|
|
|
334
|
-
|
|
335
|
-
// Required
|
|
336
|
-
apiKey: "your-loopman-api-key",
|
|
337
|
-
workflowId: "email-workflow",
|
|
434
|
+
See the [Quick Start](#quick-start) section above for a complete LangGraph workflow example with validation nodes and conditional routing.
|
|
338
435
|
|
|
339
|
-
|
|
340
|
-
executionId: "custom-execution-id", // Auto-generated if not provided
|
|
341
|
-
apiBaseUrl: "https://api.loopman.io", // Default
|
|
342
|
-
timeout: 5 * 60 * 1000, // 5 minutes
|
|
343
|
-
pollingInterval: 5000, // Poll every 5 seconds
|
|
344
|
-
debug: true, // Enable logging
|
|
345
|
-
|
|
346
|
-
// Tool configuration
|
|
347
|
-
interruptOn: {
|
|
348
|
-
send_email: true, // Requires validation
|
|
349
|
-
read_email: false, // Auto-approved
|
|
350
|
-
},
|
|
351
|
-
});
|
|
352
|
-
```
|
|
436
|
+
### Decision Routing & Feedback Loop
|
|
353
437
|
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
```mermaid
|
|
357
|
-
graph TD
|
|
358
|
-
A[Agent calls tool] --> B{Requires validation?}
|
|
359
|
-
B -->|No| C[Execute immediately]
|
|
360
|
-
B -->|Yes| D[Middleware sends to Loopman API]
|
|
361
|
-
D --> E[Middleware polls for decision]
|
|
362
|
-
E --> F[Notify user via mobile/web]
|
|
363
|
-
F --> G{Human decision}
|
|
364
|
-
G -->|Approve| H[Middleware executes as-is]
|
|
365
|
-
G -->|Edit| I[Middleware executes with modifications]
|
|
366
|
-
G -->|Reject| J[Middleware returns error message]
|
|
367
|
-
H --> K[Return result to application]
|
|
368
|
-
I --> K
|
|
369
|
-
J --> K
|
|
370
|
-
style D fill:#90EE90
|
|
371
|
-
style E fill:#90EE90
|
|
372
|
-
style H fill:#90EE90
|
|
373
|
-
style I fill:#90EE90
|
|
374
|
-
style J fill:#90EE90
|
|
375
|
-
```
|
|
438
|
+
The conditional edge routes your workflow based on human decisions:
|
|
376
439
|
|
|
377
|
-
|
|
440
|
+
- **`execute`**: Human approved ā Continue to tool execution
|
|
441
|
+
- **`rejected`**: Human rejected ā End workflow
|
|
442
|
+
- **`retry`**: Human requested changes ā **Retry agent with feedback (FEEDBACK LOOP)** š
|
|
443
|
+
- **`timeout`**: No decision within timeout ā End workflow (or fallback)
|
|
444
|
+
- **`error`**: API error ā End workflow (or fallback)
|
|
378
445
|
|
|
379
|
-
|
|
446
|
+
**The `retry` route enables the feedback loop:** When a human rejects with status `NEEDS_CHANGES` and provides feedback (e.g., "Use a more professional tone"), the workflow automatically routes back to the agent node. The feedback is injected into the agent's context via `enrichSystemPrompt()`, allowing the agent to learn and correct its decision. This creates an iterative refinement cycle that improves agent performance over time.
|
|
380
447
|
|
|
381
|
-
|
|
382
|
-
// Approve
|
|
383
|
-
{ type: "approve" }
|
|
384
|
-
|
|
385
|
-
// Edit/Modify
|
|
386
|
-
{
|
|
387
|
-
type: "edit",
|
|
388
|
-
editedAction: {
|
|
389
|
-
name: "send_email",
|
|
390
|
-
args: { to: "alice@example.com", subject: "Modified" }
|
|
391
|
-
}
|
|
392
|
-
}
|
|
448
|
+
### Running the Example
|
|
393
449
|
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
type: "reject",
|
|
397
|
-
message: "Reason for rejection"
|
|
398
|
-
}
|
|
450
|
+
```bash
|
|
451
|
+
npx tsx examples/5-langgraph-integration/loopman-validation-graph.ts
|
|
399
452
|
```
|
|
400
453
|
|
|
401
454
|
---
|
|
@@ -460,35 +513,57 @@ loopman-langchain-sdk-typescript/
|
|
|
460
513
|
|
|
461
514
|
## š API Reference
|
|
462
515
|
|
|
463
|
-
###
|
|
516
|
+
### LangGraph API
|
|
464
517
|
|
|
465
|
-
#### `
|
|
518
|
+
#### `createLoopmanContextNode(config)`
|
|
466
519
|
|
|
467
|
-
Creates a
|
|
520
|
+
Creates a LangGraph node that loads guidelines and decision history.
|
|
468
521
|
|
|
469
522
|
**Parameters:**
|
|
470
523
|
|
|
471
524
|
- `config.apiKey` (string, required): Loopman API key
|
|
472
525
|
- `config.workflowId` (string, required): Workflow identifier
|
|
473
|
-
- `config.
|
|
474
|
-
- `config.mode` (string, optional): Operation mode (`tool-validation`, `prompt-enhancement`, `full`)
|
|
475
|
-
- `config.interruptOn` (Record<string, boolean>, optional): Tool validation config
|
|
476
|
-
- `config.timeout` (number, optional): Decision timeout in ms
|
|
477
|
-
- `config.pollingInterval` (number, optional): Polling interval in ms
|
|
526
|
+
- `config.category` (string, optional): Category filter for guidelines
|
|
478
527
|
- `config.debug` (boolean, optional): Enable debug logging
|
|
479
528
|
|
|
480
|
-
**Returns:**
|
|
529
|
+
**Returns:** LangGraph node function
|
|
481
530
|
|
|
482
|
-
|
|
531
|
+
#### `createLoopmanValidationNode(config)`
|
|
483
532
|
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
533
|
+
Creates a LangGraph node that handles human validation.
|
|
534
|
+
|
|
535
|
+
**Parameters:**
|
|
536
|
+
|
|
537
|
+
- `config.apiKey` (string, required): Loopman API key
|
|
538
|
+
- `config.workflowId` (string, required): Workflow identifier
|
|
539
|
+
- `config.timeout` (number, optional): Decision timeout in ms (default: 5 minutes)
|
|
540
|
+
- `config.pollingInterval` (number, optional): Polling interval in ms (default: 5 seconds)
|
|
541
|
+
- `config.debug` (boolean, optional): Enable debug logging
|
|
542
|
+
|
|
543
|
+
**Returns:** LangGraph node function
|
|
544
|
+
|
|
545
|
+
#### `createLoopmanConditionalEdge(config)`
|
|
546
|
+
|
|
547
|
+
Creates a conditional edge for routing based on validation results.
|
|
548
|
+
|
|
549
|
+
**Parameters:**
|
|
550
|
+
|
|
551
|
+
- `config.debug` (boolean, optional): Enable debug logging
|
|
552
|
+
|
|
553
|
+
**Returns:** Conditional edge function
|
|
554
|
+
|
|
555
|
+
#### `enrichSystemPrompt(basePrompt, context, options)`
|
|
556
|
+
|
|
557
|
+
Enriches a system prompt with Loopman context.
|
|
558
|
+
|
|
559
|
+
**Parameters:**
|
|
560
|
+
|
|
561
|
+
- `basePrompt` (string): Base system prompt
|
|
562
|
+
- `context.guidelines` (array, optional): Guidelines to inject
|
|
563
|
+
- `context.decisionContext` (array, optional): Decision history to inject
|
|
564
|
+
- `options.maxDecisions` (number, optional): Max number of decisions to include
|
|
565
|
+
|
|
566
|
+
**Returns:** Enriched system prompt string
|
|
492
567
|
|
|
493
568
|
### Loopman Agent API
|
|
494
569
|
|
|
@@ -530,8 +605,6 @@ const result = await agent.processWithHumanValidation({
|
|
|
530
605
|
});
|
|
531
606
|
```
|
|
532
607
|
|
|
533
|
-
See [Loopman Agent Guide](./docs/LOOPMAN_AGENT.md) for complete API documentation.
|
|
534
|
-
|
|
535
608
|
---
|
|
536
609
|
|
|
537
610
|
## š ļø Development
|
|
@@ -595,19 +668,6 @@ See `src/loopman-middleware.ts` for the complete implementation.
|
|
|
595
668
|
|
|
596
669
|
## š Related Resources
|
|
597
670
|
|
|
598
|
-
### SDK Documentation
|
|
599
|
-
|
|
600
|
-
- [LangGraph Integration Guide](./docs/LANGGRAPH_INTEGRATION.md) - Build stateful workflows with validation nodes
|
|
601
|
-
- [LangGraph Context Enrichment](./docs/LANGGRAPH_CONTEXT_ENRICHMENT.md) - Load guidelines and decision history
|
|
602
|
-
- [LangGraph Helper Functions](./docs/LANGGRAPH_HELPERS.md) - Utility functions for context integration
|
|
603
|
-
- [LangGraph Custom State](./docs/LANGGRAPH_CUSTOM_STATE.md) - Use Loopman with your own state schema
|
|
604
|
-
- [requiresValidation Mechanism](./docs/REQUIRES_VALIDATION_MECHANISM.md) - How validation triggering works
|
|
605
|
-
- [Validation Node Context Enrichment](./docs/VALIDATION_NODE_CONTEXT_ENRICHMENT.md) - Auto context loading after validation ā New
|
|
606
|
-
- [Loopman Agent Guide](./docs/LOOPMAN_AGENT.md) - Full agent implementation with MCP
|
|
607
|
-
- [Tool Validation Mode](./docs/TOOL_VALIDATION_MODE.md) - Middleware tool validation
|
|
608
|
-
- [Auto-Correction with Feedback](./docs/AUTO_CORRECTION_WITH_FEEDBACK.md) - Agent retry patterns
|
|
609
|
-
- [Evolution to LangGraph](./docs/EVOLUTION_TO_LANGGRAPH.md) - Migration roadmap
|
|
610
|
-
|
|
611
671
|
### LangChain Documentation
|
|
612
672
|
|
|
613
673
|
- [LangChain v1.0 Quickstart](https://docs.langchain.com/oss/javascript/langchain/quickstart)
|
|
@@ -617,9 +677,9 @@ See `src/loopman-middleware.ts` for the complete implementation.
|
|
|
617
677
|
|
|
618
678
|
### Loopman Platform
|
|
619
679
|
|
|
620
|
-
- [Loopman
|
|
621
|
-
- [Loopman Web App](
|
|
622
|
-
-
|
|
680
|
+
- [Loopman Website](https://loopman.ai) - Official website and documentation
|
|
681
|
+
- [Loopman Web App](https://app.loopman.ai) - Web interface for managing workflows
|
|
682
|
+
- Loopman Mobile App - Available on iOS and Android app stores
|
|
623
683
|
|
|
624
684
|
---
|
|
625
685
|
|
|
@@ -631,7 +691,7 @@ MPL-2.0 (Mozilla Public License 2.0). See `LICENSE`.
|
|
|
631
691
|
|
|
632
692
|
## š¤ Contributing
|
|
633
693
|
|
|
634
|
-
|
|
694
|
+
Contributions are welcome! Please feel free to submit issues and pull requests on our [GitHub repository](https://github.com/Loopman-AI/loopman-langchain-sdk-typescript).
|
|
635
695
|
|
|
636
696
|
---
|
|
637
697
|
|
package/dist/templates.json
CHANGED
|
@@ -1,19 +1,19 @@
|
|
|
1
1
|
{
|
|
2
2
|
"langgraph-hello-world": {
|
|
3
3
|
"index.ts": "import { HumanMessage, ToolMessage } from \"@langchain/core/messages\";\nimport { END, MemorySaver, START, StateGraph } from \"@langchain/langgraph\";\nimport { ChatOpenAI } from \"@langchain/openai\";\nimport { config } from \"dotenv\";\nimport { tool } from \"langchain\";\nimport * as z from \"zod\";\n\nimport {\n LoopmanGraphState,\n createLoopmanConditionalEdge,\n createLoopmanContextNode,\n createLoopmanValidationNode,\n enrichSystemPrompt,\n} from \"@loopman/langchain-sdk\";\n\nconfig();\n\n// Define your tools\nconst sayHello = tool(\n ({ name }) => {\n console.log(`Hello, ${name}!`);\n return `Hello, ${name}! Welcome to Loopman.`;\n },\n {\n name: \"say_hello\",\n description: \"Say hello to someone\",\n schema: z.object({\n name: z.string().describe(\"The name of the person to greet\"),\n }),\n }\n);\n\n// Agent node with context enrichment\nasync function agentNode(state: any) {\n const { messages, guidelines, decisionContext } = state;\n\n // Enrich system prompt with guidelines and decision history\n const systemPrompt = enrichSystemPrompt(\n \"You are a helpful assistant that greets people ....\",\n { guidelines, decisionContext },\n { maxDecisions: 3 }\n );\n\n const model = new ChatOpenAI({ model: \"gpt-4o-mini\" });\n const modelWithTools = model.bindTools([sayHello]);\n\n const messagesWithContext =\n (guidelines && guidelines.length > 0) ||\n (decisionContext && decisionContext.length > 0)\n ? [{ role: \"system\", content: systemPrompt }, ...messages]\n : messages;\n\n const response = await modelWithTools.invoke(messagesWithContext);\n\n return {\n messages: [response],\n requiresValidation: response.tool_calls && response.tool_calls.length > 0,\n };\n}\n\n// Tool execution node\nasync function toolNode(state: any) {\n const { messages } = state;\n const lastMessage = messages[messages.length - 1];\n\n if (!lastMessage.tool_calls || lastMessage.tool_calls.length === 0) {\n return {};\n }\n\n const toolCall = lastMessage.tool_calls[0];\n const result = await sayHello.invoke(toolCall.args);\n\n return {\n messages: [\n new ToolMessage({\n content: result,\n tool_call_id: toolCall.id,\n }),\n ],\n };\n}\n\n// Build the graph with context loading\nconst workflow = new StateGraph(LoopmanGraphState)\n .addNode(\n \"load_context\",\n createLoopmanContextNode({\n apiKey: process.env.LOOPMAN_API_KEY!,\n workflowId: process.env.LOOPMAN_WORKFLOW_ID!,\n category: \"hello-world\",\n debug: true,\n })\n )\n .addNode(\"agent\", agentNode)\n .addNode(\n \"loopman_validation\",\n createLoopmanValidationNode({\n apiKey: process.env.LOOPMAN_API_KEY!,\n workflowId: process.env.LOOPMAN_WORKFLOW_ID!,\n debug: true,\n })\n )\n .addNode(\"tools\", toolNode)\n .addEdge(START, \"load_context\")\n .addEdge(\"load_context\", \"agent\")\n .addEdge(\"agent\", \"loopman_validation\")\n .addConditionalEdges(\n \"loopman_validation\",\n createLoopmanConditionalEdge({ debug: true }),\n {\n execute: \"tools\",\n rejected: END,\n retry: \"agent\",\n timeout: END,\n error: END,\n }\n )\n .addEdge(\"tools\", END);\n\n// Compile and run\nconst checkpointer = new MemorySaver();\nconst app = workflow.compile({ checkpointer });\n\nasync function main() {\n const config = { configurable: { thread_id: \"hello-world-thread\" } };\n const inputs = {\n messages: [new HumanMessage(\"Say hello to Alice\")],\n };\n\n console.log(\"Starting LangGraph workflow with context enrichment...\");\n\n for await (const output of await app.stream(inputs, config)) {\n const nodeName = Object.keys(output)[0];\n console.log(`Step: ${nodeName}`);\n }\n\n const finalState = await app.getState(config);\n console.log(\"Final status:\", finalState.values.loopmanTaskStatus);\n console.log(\"Guidelines loaded:\", finalState.values.guidelines?.length || 0);\n console.log(\n \"Decision context loaded:\",\n finalState.values.decisionContext?.length || 0\n );\n console.log(\"Workflow completed!\");\n}\n\nmain().catch(console.error);\n",
|
|
4
|
-
"package.json": "{\n \"name\": \"loopman-langgraph-hello-world\",\n \"version\": \"1.0.0\",\n \"description\": \"Loopman LangGraph Hello World Example\",\n \"main\": \"index.ts\",\n \"type\": \"module\",\n \"scripts\": {\n \"start\": \"tsx index.ts\",\n \"dev\": \"tsx index.ts\",\n \"build\": \"tsc\",\n \"run\": \"node dist/index.js\"\n },\n \"dependencies\": {\n \"@langchain/core\": \"^1.0.2\",\n \"@langchain/langgraph\": \"^1.0.1\",\n \"@langchain/openai\": \"^1.0.0\",\n \"@loopman/langchain-sdk\": \"^1.12.
|
|
4
|
+
"package.json": "{\n \"name\": \"loopman-langgraph-hello-world\",\n \"version\": \"1.0.0\",\n \"description\": \"Loopman LangGraph Hello World Example\",\n \"main\": \"index.ts\",\n \"type\": \"module\",\n \"scripts\": {\n \"start\": \"tsx index.ts\",\n \"dev\": \"tsx index.ts\",\n \"build\": \"tsc\",\n \"run\": \"node dist/index.js\"\n },\n \"dependencies\": {\n \"@langchain/core\": \"^1.0.2\",\n \"@langchain/langgraph\": \"^1.0.1\",\n \"@langchain/openai\": \"^1.0.0\",\n \"@loopman/langchain-sdk\": \"^1.12.2\",\n \"dotenv\": \"^17.2.3\",\n \"langchain\": \"^1.0.2\",\n \"tsx\": \"^4.20.6\",\n \"typescript\": \"^5.9.3\",\n \"zod\": \"^3.25.76\"\n },\n \"devDependencies\": {\n \"@types/node\": \"^24.9.2\"\n }\n}\n",
|
|
5
5
|
"tsconfig.json": "{\n \"compilerOptions\": {\n \"target\": \"ES2022\",\n \"module\": \"ES2022\",\n \"lib\": [\"ES2022\"],\n \"moduleResolution\": \"bundler\",\n \"resolveJsonModule\": true,\n \"allowJs\": true,\n \"outDir\": \"./dist\",\n \"rootDir\": \"./\",\n \"strict\": true,\n \"esModuleInterop\": true,\n \"skipLibCheck\": true,\n \"forceConsistentCasingInFileNames\": true,\n \"declaration\": true,\n \"declarationMap\": true,\n \"sourceMap\": true\n },\n \"include\": [\"**/*.ts\"],\n \"exclude\": [\"node_modules\", \"dist\"]\n}\n\n",
|
|
6
6
|
"README.md": "# Loopman LangGraph Hello World\n\nThis project demonstrates how to integrate Loopman with LangGraph using Context Enrichment / Feedback Loop mode.\n\n## About LangGraph\n\nLangGraph is LangChain's official framework for building stateful, multi-actor applications with LLMs. It provides:\n\n- **Stateful workflows**: Explicit state management across nodes\n- **Conditional routing**: Dynamic edges based on state\n- **Streaming support**: Real-time updates during execution\n- **Visual debugging**: Graph visualization and inspection\n\n## Setup\n\n1. Install dependencies:\n```bash\nnpm install\n```\n\n2. Copy .env.example to .env and configure your keys:\n```bash\ncp .env.example .env\n```\n\nEdit the .env file and replace the placeholders with your actual values:\n- `OPENAI_API_KEY`: Your OpenAI API key\n- `LOOPMAN_API_KEY`: Your Loopman API key\n- `LOOPMAN_WORKFLOW_ID`: Your workflow ID from Loopman\n\n3. Run the example:\n```bash\nnpm start\n```\n\n## Graph Architecture\n\nThe workflow follows this pattern:\n\n```\nSTART\n ā\nload_context (load guidelines and decision history)\n ā\nagent (LLM decides action)\n ā\nloopman_validation (create task + poll)\n ā\n[conditional edge based on status]\n ā\nāāā tools (APPROVED: execute)\nāāā agent (NEEDS_CHANGES: retry)\nāāā END (REJECTED/TIMEOUT/ERROR: end)\n ā\nEND\n```\n\n## Key Features\n\n- **Context Enrichment**: Loads validation guidelines and historical decisions\n- **Prompt Enhancement**: Automatically enriches system prompts with context\n- **Learning from History**: Agent learns from past human decisions\n- **Category Filtering**: Guidelines filtered by category for relevance\n- **Feedback Loop**: Human feedback is stored and used to improve future decisions\n\n## Learn More\n\n- [LangGraph Documentation](https://js.langchain.com/docs/langgraph/)\n- [Loopman LangGraph Integration Guide](https://github.com/loopman/loopman-langchain-sdk/blob/main/docs/LANGGRAPH_INTEGRATION.md)\n- [Loopman Documentation](https://loopman.dev/docs)\n\n"
|
|
7
7
|
},
|
|
8
8
|
"langchain-tool-validation": {
|
|
9
9
|
"index.ts": "import { MemorySaver } from \"@langchain/langgraph\";\nimport { config } from \"dotenv\";\nimport { createAgent, tool } from \"langchain\";\nimport * as z from \"zod\";\nimport { loopmanMiddleware } from \"@loopman/langchain-sdk\";\n\n// Load environment variables\nconfig();\n\n// Simple hello world tool\nconst sayHello = tool(\n ({ name }) => {\n console.log(`Hello, ${name}!`);\n return `Hello, ${name}! Welcome to Loopman.`;\n },\n {\n name: \"say_hello\",\n description: \"Say hello to someone\",\n schema: z.object({\n name: z.string().describe(\"The name of the person to greet\"),\n }),\n }\n);\n\n// Create agent with Loopman middleware\nconst checkpointer = new MemorySaver();\n\nconst agent = createAgent({\n model: \"openai:gpt-4o-mini\",\n systemPrompt: \"You are a helpful assistant that greets people.\",\n tools: [sayHello],\n middleware: [\n loopmanMiddleware({\n apiKey: process.env.LOOPMAN_API_KEY!,\n workflowId: process.env.LOOPMAN_WORKFLOW_ID!,\n interruptOn: {\n say_hello: true, // Requires human validation\n },\n debug: true,\n }),\n ],\n checkpointer,\n});\n\n// Run the agent\nasync function main() {\n const config = { configurable: { thread_id: \"hello-world-thread\" } };\n\n const result = await agent.invoke(\n {\n messages: [\n {\n role: \"user\",\n content: \"Say hello to Alice\",\n },\n ],\n },\n config\n );\n\n console.log(\"Agent response:\", result.messages[result.messages.length - 1].content);\n}\n\nmain().catch(console.error);\n\n",
|
|
10
|
-
"package.json": "{\n \"name\": \"loopman-langchain-tool-validation\",\n \"version\": \"1.0.0\",\n \"description\": \"Loopman LangChain Tool Validation Example\",\n \"main\": \"index.ts\",\n \"type\": \"module\",\n \"scripts\": {\n \"start\": \"tsx index.ts\",\n \"dev\": \"tsx index.ts\",\n \"build\": \"tsc\",\n \"run\": \"node dist/index.js\"\n },\n \"dependencies\": {\n \"@langchain/core\": \"^1.0.2\",\n \"@langchain/mcp-adapters\": \"^1.0.0\",\n \"@langchain/langgraph\": \"^1.0.1\",\n \"@langchain/openai\": \"^1.0.0\",\n \"@loopman/langchain-sdk\": \"^1.12.
|
|
10
|
+
"package.json": "{\n \"name\": \"loopman-langchain-tool-validation\",\n \"version\": \"1.0.0\",\n \"description\": \"Loopman LangChain Tool Validation Example\",\n \"main\": \"index.ts\",\n \"type\": \"module\",\n \"scripts\": {\n \"start\": \"tsx index.ts\",\n \"dev\": \"tsx index.ts\",\n \"build\": \"tsc\",\n \"run\": \"node dist/index.js\"\n },\n \"dependencies\": {\n \"@langchain/core\": \"^1.0.2\",\n \"@langchain/mcp-adapters\": \"^1.0.0\",\n \"@langchain/langgraph\": \"^1.0.1\",\n \"@langchain/openai\": \"^1.0.0\",\n \"@loopman/langchain-sdk\": \"^1.12.2\",\n \"dotenv\": \"^17.2.3\",\n \"langchain\": \"^1.0.2\",\n \"tsx\": \"^4.20.6\",\n \"typescript\": \"^5.9.3\",\n \"zod\": \"^3.25.76\"\n },\n \"devDependencies\": {\n \"@types/node\": \"^24.9.2\"\n }\n}\n\n",
|
|
11
11
|
"tsconfig.json": "{\n \"compilerOptions\": {\n \"target\": \"ES2022\",\n \"module\": \"ES2022\",\n \"lib\": [\"ES2022\"],\n \"moduleResolution\": \"bundler\",\n \"resolveJsonModule\": true,\n \"allowJs\": true,\n \"outDir\": \"./dist\",\n \"rootDir\": \"./\",\n \"strict\": true,\n \"esModuleInterop\": true,\n \"skipLibCheck\": true,\n \"forceConsistentCasingInFileNames\": true,\n \"declaration\": true,\n \"declarationMap\": true,\n \"sourceMap\": true\n },\n \"include\": [\"**/*.ts\"],\n \"exclude\": [\"node_modules\", \"dist\"]\n}\n\n",
|
|
12
12
|
"README.md": "# Loopman LangChain - Tool Validation Mode\n\nThis project demonstrates how to integrate Loopman with LangChain using **Tool Validation** mode.\n\n## About Tool Validation Mode\n\nIn this mode, Loopman middleware intercepts specific tool calls and requires human validation before execution. This is useful when:\n- Certain actions need human approval (e.g., sending emails, making payments)\n- You want to validate AI decisions before they affect real systems\n- Compliance requires human oversight for specific operations\n\n## Setup\n\n1. Install dependencies:\n```bash\nnpm install\n```\n\n2. Copy .env.example to .env and configure your keys:\n```bash\ncp .env.example .env\n```\n\nEdit the .env file and replace the placeholders with your actual values:\n- `OPENAI_API_KEY`: Your OpenAI API key\n- `LOOPMAN_API_KEY`: Your Loopman API key\n- `LOOPMAN_WORKFLOW_ID`: Your workflow ID from Loopman\n\n3. Run the example:\n```bash\nnpm start\n```\n\n## How It Works\n\n### 1. Define Tools\n\n```typescript\nconst sayHello = tool(\n ({ name }) => {\n console.log(`Hello, ${name}!`);\n return `Hello, ${name}! Welcome to Loopman.`;\n },\n {\n name: \"say_hello\",\n description: \"Say hello to someone\",\n schema: z.object({\n name: z.string().describe(\"The name of the person to greet\"),\n }),\n }\n);\n```\n\n### 2. Add Loopman Middleware\n\n```typescript\nconst agent = createAgent({\n model: \"openai:gpt-4o-mini\",\n tools: [sayHello],\n middleware: [\n loopmanMiddleware({\n apiKey: process.env.LOOPMAN_API_KEY!,\n workflowId: process.env.LOOPMAN_WORKFLOW_ID!,\n interruptOn: {\n say_hello: true, // Requires human validation\n },\n debug: true,\n }),\n ],\n checkpointer,\n});\n```\n\n### 3. Run the Agent\n\n```typescript\nconst result = await agent.invoke(\n {\n messages: [{ role: \"user\", content: \"Say hello to Alice\" }],\n },\n config\n);\n```\n\n## Key Features\n\n- **Selective Validation**: Only specified tools require approval\n- **Automatic Interception**: Middleware handles validation workflow\n- **Stateful**: Uses checkpointer to maintain conversation state\n- **Debug Mode**: Verbose logging for development\n\n## Workflow\n\n```\n1. User sends message\n ā\n2. Agent generates tool call (say_hello)\n ā\n3. Loopman middleware intercepts\n ā\n4. Creates validation task\n ā\n5. Waits for human decision\n ā\n6. If approved ā Execute tool\n If rejected ā Return to agent with feedback\n```\n\n## Configuration Options\n\n### interruptOn\n\nSpecify which tools require validation:\n\n```typescript\ninterruptOn: {\n say_hello: true, // Always validate\n send_email: true, // Always validate\n get_weather: false, // Never validate (auto-execute)\n}\n```\n\n### debug\n\nEnable/disable verbose logging:\n\n```typescript\ndebug: true // Show detailed logs\ndebug: false // Production mode\n```\n\n## Learn More\n\n- [Loopman Middleware Documentation](https://github.com/loopman/loopman-langchain-sdk/blob/main/docs/TOOL_VALIDATION_MODE.md)\n- [LangChain Agent Documentation](https://js.langchain.com/docs/how_to/agent_executor)\n- [Loopman Documentation](https://loopman.dev/docs)\n\n"
|
|
13
13
|
},
|
|
14
14
|
"langchain-full-review": {
|
|
15
15
|
"index.ts": "import { config } from \"dotenv\";\nimport { tool } from \"langchain\";\nimport * as z from \"zod\";\nimport { createLoopmanAgent } from \"@loopman/langchain-sdk\";\n\n// Load environment variables\nconfig();\n\n// Simple hello world tool\nconst sayHello = tool(\n ({ name }) => {\n console.log(`Hello, ${name}!`);\n return `Hello, ${name}! Welcome to Loopman.`;\n },\n {\n name: \"say_hello\",\n description: \"Say hello to someone\",\n schema: z.object({\n name: z.string().describe(\"The name of the person to greet\"),\n }),\n }\n);\n\n// Create Loopman agent with full human review process\nconst agent = createLoopmanAgent({\n apiKey: process.env.LOOPMAN_API_KEY!,\n workflowId: process.env.LOOPMAN_WORKFLOW_ID!,\n model: \"openai:gpt-4o-mini\",\n systemPrompt: \"You are a helpful assistant that greets people.\",\n category: \"hello-world\",\n additionalTools: [sayHello],\n requireApprovalForTools: [\"say_hello\"], // Requires validation\n debug: true,\n});\n\n// Run the agent\nasync function main() {\n const result = await agent.processWithHumanValidation({\n input: \"Say hello to Alice\",\n });\n\n console.log(\"Agent response:\", result.response);\n if (result.decision) {\n console.log(\"Decision status:\", result.decision.status);\n if (result.decision.feedback) {\n console.log(\"Human feedback:\", result.decision.feedback);\n }\n }\n\n await agent.disconnect();\n}\n\nmain().catch(console.error);\n\n",
|
|
16
|
-
"package.json": "{\n \"name\": \"loopman-langchain-full-review\",\n \"version\": \"1.0.0\",\n \"description\": \"Loopman LangChain Full Human Review Example\",\n \"main\": \"index.ts\",\n \"type\": \"module\",\n \"scripts\": {\n \"start\": \"tsx index.ts\",\n \"dev\": \"tsx index.ts\",\n \"build\": \"tsc\",\n \"run\": \"node dist/index.js\"\n },\n \"dependencies\": {\n \"@langchain/core\": \"^1.0.2\",\n \"@langchain/mcp-adapters\": \"^1.0.0\",\n \"@langchain/langgraph\": \"^1.0.1\",\n \"@langchain/openai\": \"^1.0.0\",\n \"@loopman/langchain-sdk\": \"^1.12.
|
|
16
|
+
"package.json": "{\n \"name\": \"loopman-langchain-full-review\",\n \"version\": \"1.0.0\",\n \"description\": \"Loopman LangChain Full Human Review Example\",\n \"main\": \"index.ts\",\n \"type\": \"module\",\n \"scripts\": {\n \"start\": \"tsx index.ts\",\n \"dev\": \"tsx index.ts\",\n \"build\": \"tsc\",\n \"run\": \"node dist/index.js\"\n },\n \"dependencies\": {\n \"@langchain/core\": \"^1.0.2\",\n \"@langchain/mcp-adapters\": \"^1.0.0\",\n \"@langchain/langgraph\": \"^1.0.1\",\n \"@langchain/openai\": \"^1.0.0\",\n \"@loopman/langchain-sdk\": \"^1.12.2\",\n \"dotenv\": \"^17.2.3\",\n \"langchain\": \"^1.0.2\",\n \"tsx\": \"^4.20.6\",\n \"typescript\": \"^5.9.3\",\n \"zod\": \"^3.25.76\"\n },\n \"devDependencies\": {\n \"@types/node\": \"^24.9.2\"\n }\n}\n\n",
|
|
17
17
|
"tsconfig.json": "{\n \"compilerOptions\": {\n \"target\": \"ES2022\",\n \"module\": \"ES2022\",\n \"lib\": [\"ES2022\"],\n \"moduleResolution\": \"bundler\",\n \"resolveJsonModule\": true,\n \"allowJs\": true,\n \"outDir\": \"./dist\",\n \"rootDir\": \"./\",\n \"strict\": true,\n \"esModuleInterop\": true,\n \"skipLibCheck\": true,\n \"forceConsistentCasingInFileNames\": true,\n \"declaration\": true,\n \"declarationMap\": true,\n \"sourceMap\": true\n },\n \"include\": [\"**/*.ts\"],\n \"exclude\": [\"node_modules\", \"dist\"]\n}\n\n",
|
|
18
18
|
"README.md": "# Loopman LangChain - Full Human Review Mode\n\nThis project demonstrates how to integrate Loopman with LangChain using **Full Human Review Process** mode.\n\n## About Full Human Review Mode\n\nIn this mode, the Loopman Agent handles the entire workflow including:\n- Creating validation tasks\n- Waiting for human approval\n- Handling feedback and retries\n- Managing the complete lifecycle\n\nThis is useful when:\n- You want a complete HITL (Human-In-The-Loop) solution\n- The agent should wait for human decisions before proceeding\n- You need full control over the validation workflow\n\n## Setup\n\n1. Install dependencies:\n```bash\nnpm install\n```\n\n2. Copy .env.example to .env and configure your keys:\n```bash\ncp .env.example .env\n```\n\nEdit the .env file and replace the placeholders with your actual values:\n- `OPENAI_API_KEY`: Your OpenAI API key\n- `LOOPMAN_API_KEY`: Your Loopman API key\n- `LOOPMAN_WORKFLOW_ID`: Your workflow ID from Loopman\n\n3. Run the example:\n```bash\nnpm start\n```\n\n## How It Works\n\n### 1. Define Tools\n\n```typescript\nconst sayHello = tool(\n ({ name }) => {\n console.log(`Hello, ${name}!`);\n return `Hello, ${name}! Welcome to Loopman.`;\n },\n {\n name: \"say_hello\",\n description: \"Say hello to someone\",\n schema: z.object({\n name: z.string().describe(\"The name of the person to greet\"),\n }),\n }\n);\n```\n\n### 2. Create Loopman Agent\n\n```typescript\nconst agent = createLoopmanAgent({\n apiKey: process.env.LOOPMAN_API_KEY!,\n workflowId: process.env.LOOPMAN_WORKFLOW_ID!,\n model: \"openai:gpt-4o-mini\",\n systemPrompt: \"You are a helpful assistant that greets people.\",\n category: \"hello-world\",\n additionalTools: [sayHello],\n requireApprovalForTools: [\"say_hello\"],\n debug: true,\n});\n```\n\n### 3. Process with Human Validation\n\n```typescript\nconst result = await agent.processWithHumanValidation({\n input: \"Say hello to Alice\",\n});\n\nconsole.log(\"Agent response:\", result.response);\nif (result.decision) {\n console.log(\"Decision status:\", result.decision.status);\n console.log(\"Human feedback:\", result.decision.feedback);\n}\n```\n\n## Key Features\n\n- **Complete HITL Workflow**: Agent manages the entire validation lifecycle\n- **Automatic Polling**: Waits for human decisions\n- **Feedback Handling**: Processes human feedback and retries if needed\n- **Category Support**: Organize validations by category\n- **Debug Mode**: Verbose logging for development\n\n## Workflow\n\n```\n1. User sends message\n ā\n2. Agent processes with LLM\n ā\n3. Agent generates tool call\n ā\n4. Creates Loopman validation task\n ā\n5. Polls for human decision\n ā\n6. If approved ā Execute and return result\n If rejected ā Process feedback and retry\n If timeout ā Handle timeout\n```\n\n## Configuration Options\n\n### requireApprovalForTools\n\nSpecify which tools require validation:\n\n```typescript\nrequireApprovalForTools: [\"say_hello\", \"send_email\"]\n// Only these tools will require human approval\n```\n\n### category\n\nOrganize validations by category:\n\n```typescript\ncategory: \"hello-world\"\n// Helps filter and organize validation tasks\n```\n\n### debug\n\nEnable/disable verbose logging:\n\n```typescript\ndebug: true // Show detailed logs\ndebug: false // Production mode\n```\n\n## Response Structure\n\nThe `processWithHumanValidation` method returns:\n\n```typescript\n{\n response: string, // Final agent response\n decision?: {\n status: \"APPROVED\" | \"REJECTED\" | \"NEEDS_CHANGES\",\n feedback?: string, // Human feedback if provided\n createdAt: Date,\n updatedAt: Date,\n }\n}\n```\n\n## Learn More\n\n- [Loopman Agent Documentation](https://github.com/loopman/loopman-langchain-sdk/blob/main/docs/LOOPMAN_AGENT.md)\n- [LangChain Documentation](https://js.langchain.com/docs)\n- [Loopman Documentation](https://loopman.dev/docs)\n\n"
|
|
19
19
|
}
|
|
@@ -15,7 +15,7 @@
|
|
|
15
15
|
"@langchain/mcp-adapters": "^1.0.0",
|
|
16
16
|
"@langchain/langgraph": "^1.0.1",
|
|
17
17
|
"@langchain/openai": "^1.0.0",
|
|
18
|
-
"@loopman/langchain-sdk": "^1.12.
|
|
18
|
+
"@loopman/langchain-sdk": "^1.12.2",
|
|
19
19
|
"dotenv": "^17.2.3",
|
|
20
20
|
"langchain": "^1.0.2",
|
|
21
21
|
"tsx": "^4.20.6",
|
|
@@ -15,7 +15,7 @@
|
|
|
15
15
|
"@langchain/mcp-adapters": "^1.0.0",
|
|
16
16
|
"@langchain/langgraph": "^1.0.1",
|
|
17
17
|
"@langchain/openai": "^1.0.0",
|
|
18
|
-
"@loopman/langchain-sdk": "^1.12.
|
|
18
|
+
"@loopman/langchain-sdk": "^1.12.2",
|
|
19
19
|
"dotenv": "^17.2.3",
|
|
20
20
|
"langchain": "^1.0.2",
|
|
21
21
|
"tsx": "^4.20.6",
|