@loopman/langchain-sdk 1.12.1 ā 1.12.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md
CHANGED
|
@@ -1,65 +1,99 @@
|
|
|
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](https://loopman.ai).
|
|
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](https://app.loopman.ai), 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](https://loopman.ai)** 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
|
+
- ā
**Human Rejection with Feedback**: When humans reject a decision, they can provide detailed feedback explaining why
|
|
61
|
+
- ā
**Automatic Agent Retry**: The agent receives the feedback and automatically retries with corrections
|
|
62
|
+
- ā
**Context Learning**: Feedback is stored in decision history and injected into future agent prompts
|
|
63
|
+
- ā
**Iterative Refinement**: Agents learn from past mistakes and improve over time
|
|
64
|
+
- ā
**Workflow Routing**: LangGraph conditional edges automatically route to retry logic on `NEEDS_CHANGES` status
|
|
65
|
+
|
|
66
|
+
**Example workflow:**
|
|
67
|
+
|
|
68
|
+
1. Agent proposes to send an email with incorrect tone
|
|
69
|
+
2. Human rejects with feedback: "Use a more professional tone"
|
|
70
|
+
3. Agent receives feedback and retries with corrected tone
|
|
71
|
+
4. Human approves the refined version
|
|
72
|
+
5. Future similar tasks benefit from this learned context
|
|
73
|
+
|
|
74
|
+
### š LangGraph Support
|
|
75
|
+
|
|
76
|
+
- ā
**Validation Nodes**: Reusable nodes for human approval workflows
|
|
77
|
+
- ā
**Conditional Routing**: Route based on human decisions (approve/reject/retry)
|
|
78
|
+
- ā
**Context Loading**: Automatic guidelines and decision history retrieval
|
|
79
|
+
- ā
**State Management**: Full integration with LangGraph state
|
|
80
|
+
- ā
**Helper Functions**: `enrichSystemPrompt()` for context injection
|
|
81
|
+
|
|
36
82
|
### š¤ Agent Capabilities
|
|
37
83
|
|
|
84
|
+
- ā
**High-Level Agent API**: `createLoopmanAgent()` for quick setup
|
|
38
85
|
- ā
**Tool Calling**: Dynamic tool execution with Zod validation
|
|
39
86
|
- ā
**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
|
|
87
|
+
- ā
**MCP Integration**: Model Context Protocol support for advanced workflows
|
|
88
|
+
- ā
**Double Validation Layer**: Global + tool-specific validation
|
|
56
89
|
|
|
57
90
|
### š§ Developer Experience
|
|
58
91
|
|
|
59
|
-
- ā
**TypeScript**: Full type safety with
|
|
92
|
+
- ā
**TypeScript**: Full type safety with comprehensive types
|
|
93
|
+
- ā
**Multiple Integration Patterns**: Middleware, Agent API, LangGraph nodes
|
|
60
94
|
- ā
**Debugging**: VSCode launch configurations
|
|
61
|
-
- ā
**Examples**:
|
|
62
|
-
- ā
**Documentation**: Inline comments and guides
|
|
95
|
+
- ā
**Real-World Examples**: Production-ready code samples
|
|
96
|
+
- ā
**Comprehensive Documentation**: Inline comments and guides
|
|
63
97
|
|
|
64
98
|
---
|
|
65
99
|
|
|
@@ -67,6 +101,7 @@ Perfect for learning agent patterns, HITL workflows, and building production-rea
|
|
|
67
101
|
|
|
68
102
|
- **Node.js**: 18+
|
|
69
103
|
- **OpenAI API Key**: Required for model calls
|
|
104
|
+
- **Loopman Account**: Sign up at [https://app.loopman.ai](https://app.loopman.ai) to get your API key
|
|
70
105
|
- **npm/yarn**: Package manager
|
|
71
106
|
|
|
72
107
|
---
|
|
@@ -91,7 +126,7 @@ Edit `.env` and add your API keys:
|
|
|
91
126
|
|
|
92
127
|
```env
|
|
93
128
|
OPENAI_API_KEY=sk-your-openai-api-key-here
|
|
94
|
-
LOOPMAN_API_KEY=your-loopman-api-key-here #
|
|
129
|
+
LOOPMAN_API_KEY=your-loopman-api-key-here # Get your API key at https://app.loopman.ai
|
|
95
130
|
```
|
|
96
131
|
|
|
97
132
|
---
|
|
@@ -130,46 +165,29 @@ const result = await agent.invoke(
|
|
|
130
165
|
);
|
|
131
166
|
```
|
|
132
167
|
|
|
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
|
|
168
|
+
### Middleware Integration (Standard HITL Process)
|
|
156
169
|
|
|
157
170
|
```typescript
|
|
158
|
-
import {
|
|
171
|
+
import { createAgent } from "langchain";
|
|
172
|
+
import { loopmanMiddleware } from "@loopman/langchain-sdk";
|
|
173
|
+
import { MemorySaver } from "@langchain/langgraph";
|
|
159
174
|
|
|
175
|
+
// Create agent with Loopman middleware
|
|
160
176
|
const agent = createAgent({
|
|
161
177
|
model: "openai:gpt-4o-mini",
|
|
162
|
-
tools: [sendEmail],
|
|
178
|
+
tools: [sendEmail, readEmail],
|
|
163
179
|
middleware: [
|
|
164
180
|
loopmanMiddleware({
|
|
165
181
|
apiKey: process.env.LOOPMAN_API_KEY!,
|
|
166
182
|
workflowId: "email-workflow",
|
|
183
|
+
mode: "tool-validation", // or "prompt-enhancement" or "full"
|
|
167
184
|
interruptOn: {
|
|
168
185
|
send_email: true, // Requires validation
|
|
169
186
|
read_email: false, // Auto-approved
|
|
170
187
|
},
|
|
188
|
+
timeout: 5 * 60 * 1000, // 5 minutes
|
|
171
189
|
pollingInterval: 5000, // Poll every 5 seconds
|
|
172
|
-
|
|
190
|
+
debug: true,
|
|
173
191
|
}),
|
|
174
192
|
],
|
|
175
193
|
checkpointer: new MemorySaver(),
|
|
@@ -185,49 +203,157 @@ const result = await agent.invoke(
|
|
|
185
203
|
// ā
Middleware handles HITL transparently
|
|
186
204
|
```
|
|
187
205
|
|
|
188
|
-
###
|
|
206
|
+
### Loopman Agent (Complete Solution - Ready to Use)
|
|
207
|
+
|
|
208
|
+
**What's the difference with Middleware?**
|
|
209
|
+
|
|
210
|
+
The **Middleware** requires you to build and configure your own agent, then add validation on top.
|
|
211
|
+
|
|
212
|
+
The **Loopman Agent** is a **ready-to-use agent** that includes everything:
|
|
213
|
+
|
|
214
|
+
- ā
Pre-built agent with validation already integrated
|
|
215
|
+
- ā
Automatic loading of guidelines and past decisions (feedback loop)
|
|
216
|
+
- ā
Simple API: just call `processWithHumanValidation()`
|
|
217
|
+
- ā
No manual configuration needed
|
|
218
|
+
|
|
219
|
+
**Perfect for:** Quick start, prototyping, or when you want a complete solution out-of-the-box.
|
|
220
|
+
|
|
221
|
+
```typescript
|
|
222
|
+
import { createLoopmanAgent } from "@loopman/langchain-sdk";
|
|
223
|
+
|
|
224
|
+
const agent = createLoopmanAgent({
|
|
225
|
+
apiKey: process.env.LOOPMAN_API_KEY!,
|
|
226
|
+
workflowId: "email-workflow",
|
|
227
|
+
model: "openai:gpt-4o-mini",
|
|
228
|
+
systemPrompt: "You are a helpful email assistant",
|
|
229
|
+
additionalTools: [sendEmail, readEmail],
|
|
230
|
+
requireApprovalForTools: ["send_email"], // Only email sending requires approval
|
|
231
|
+
debug: true,
|
|
232
|
+
});
|
|
233
|
+
|
|
234
|
+
// Usage - Simple and transparent!
|
|
235
|
+
const result = await agent.processWithHumanValidation({
|
|
236
|
+
input: "Send email to alice@example.com about the meeting",
|
|
237
|
+
});
|
|
238
|
+
// ā
Agent automatically handles validation via Loopman platform (https://app.loopman.ai)
|
|
239
|
+
```
|
|
240
|
+
|
|
241
|
+
### LangGraph Integration (Recommended)
|
|
189
242
|
|
|
190
243
|
```typescript
|
|
191
244
|
import {
|
|
192
245
|
LoopmanGraphState,
|
|
193
246
|
createLoopmanContextNode,
|
|
247
|
+
createLoopmanValidationNode,
|
|
248
|
+
createLoopmanConditionalEdge,
|
|
194
249
|
enrichSystemPrompt,
|
|
195
|
-
} from "loopman
|
|
196
|
-
import { StateGraph } from "@langchain/langgraph";
|
|
250
|
+
} from "@loopman/langchain-sdk";
|
|
251
|
+
import { StateGraph, START, END } from "@langchain/langgraph";
|
|
252
|
+
import { ChatOpenAI } from "@langchain/openai";
|
|
197
253
|
|
|
198
254
|
// 1. Create context node to load guidelines and decision history
|
|
199
255
|
const contextNode = createLoopmanContextNode({
|
|
200
256
|
apiKey: process.env.LOOPMAN_API_KEY!,
|
|
201
257
|
workflowId: "my-workflow",
|
|
202
258
|
category: "email",
|
|
259
|
+
debug: true,
|
|
203
260
|
});
|
|
204
261
|
|
|
205
|
-
// 2.
|
|
262
|
+
// 2. Create validation node for human approval
|
|
263
|
+
const validationNode = createLoopmanValidationNode({
|
|
264
|
+
apiKey: process.env.LOOPMAN_API_KEY!,
|
|
265
|
+
workflowId: "my-workflow",
|
|
266
|
+
debug: true,
|
|
267
|
+
});
|
|
268
|
+
|
|
269
|
+
// 3. Agent node with context-enriched prompts
|
|
206
270
|
async function agentNode(state: typeof LoopmanGraphState.State) {
|
|
207
271
|
const { messages, guidelines, decisionContext } = state;
|
|
208
272
|
|
|
209
273
|
// ⨠Automatically enrich system prompt with Loopman context
|
|
210
|
-
const systemPrompt = enrichSystemPrompt(
|
|
211
|
-
|
|
212
|
-
decisionContext,
|
|
213
|
-
|
|
274
|
+
const systemPrompt = enrichSystemPrompt(
|
|
275
|
+
"You are a helpful email assistant.",
|
|
276
|
+
{ guidelines, decisionContext },
|
|
277
|
+
{ maxDecisions: 3 } // Show last 3 decisions
|
|
278
|
+
);
|
|
279
|
+
|
|
280
|
+
const model = new ChatOpenAI({ model: "gpt-4o-mini" });
|
|
281
|
+
const modelWithTools = model.bindTools([sendEmail]);
|
|
214
282
|
|
|
215
|
-
const
|
|
283
|
+
const messagesWithContext = [
|
|
216
284
|
{ role: "system", content: systemPrompt },
|
|
217
285
|
...messages,
|
|
218
|
-
]
|
|
286
|
+
];
|
|
219
287
|
|
|
220
|
-
|
|
288
|
+
const response = await modelWithTools.invoke(messagesWithContext);
|
|
289
|
+
|
|
290
|
+
return {
|
|
291
|
+
messages: [response],
|
|
292
|
+
requiresValidation: response.tool_calls && response.tool_calls.length > 0,
|
|
293
|
+
};
|
|
221
294
|
}
|
|
222
295
|
|
|
223
|
-
//
|
|
296
|
+
// 4. Tool execution node
|
|
297
|
+
async function toolNode(state: typeof LoopmanGraphState.State) {
|
|
298
|
+
const { messages } = state;
|
|
299
|
+
const lastMessage = messages[messages.length - 1];
|
|
300
|
+
|
|
301
|
+
if (!lastMessage.tool_calls || lastMessage.tool_calls.length === 0) {
|
|
302
|
+
return {};
|
|
303
|
+
}
|
|
304
|
+
|
|
305
|
+
const toolCall = lastMessage.tool_calls[0];
|
|
306
|
+
const result = await sendEmail.invoke(toolCall.args);
|
|
307
|
+
|
|
308
|
+
return {
|
|
309
|
+
messages: [
|
|
310
|
+
new ToolMessage({
|
|
311
|
+
content: typeof result === "string" ? result : JSON.stringify(result),
|
|
312
|
+
tool_call_id: toolCall.id,
|
|
313
|
+
}),
|
|
314
|
+
],
|
|
315
|
+
requiresValidation: false,
|
|
316
|
+
};
|
|
317
|
+
}
|
|
318
|
+
|
|
319
|
+
// 5. Build workflow with validation and conditional routing
|
|
224
320
|
const workflow = new StateGraph(LoopmanGraphState)
|
|
225
321
|
.addNode("load_context", contextNode)
|
|
226
322
|
.addNode("agent", agentNode)
|
|
323
|
+
.addNode("loopman_validation", validationNode)
|
|
324
|
+
.addNode("tools", toolNode)
|
|
325
|
+
|
|
227
326
|
.addEdge(START, "load_context")
|
|
228
|
-
.addEdge("load_context", "agent")
|
|
327
|
+
.addEdge("load_context", "agent")
|
|
328
|
+
.addEdge("agent", "loopman_validation")
|
|
329
|
+
.addConditionalEdges(
|
|
330
|
+
"loopman_validation",
|
|
331
|
+
createLoopmanConditionalEdge({ debug: true }),
|
|
332
|
+
{
|
|
333
|
+
execute: "tools", // APPROVED ā execute tool
|
|
334
|
+
rejected: END, // REJECTED ā end workflow
|
|
335
|
+
retry: "agent", // NEEDS_CHANGES with feedback ā retry agent (FEEDBACK LOOP!)
|
|
336
|
+
timeout: END, // TIMEOUT ā end workflow
|
|
337
|
+
error: END, // ERROR ā end workflow
|
|
338
|
+
}
|
|
339
|
+
)
|
|
340
|
+
.addEdge("tools", END);
|
|
341
|
+
|
|
342
|
+
const app = workflow.compile({ checkpointer: new MemorySaver() });
|
|
229
343
|
```
|
|
230
344
|
|
|
345
|
+
**š Feedback Loop in Action:**
|
|
346
|
+
|
|
347
|
+
When a human rejects a decision with status `NEEDS_CHANGES`:
|
|
348
|
+
|
|
349
|
+
1. The validation node stores the human's feedback in `decisionContext`
|
|
350
|
+
2. The conditional edge routes to `retry: "agent"` instead of ending
|
|
351
|
+
3. The agent node receives the feedback via `enrichSystemPrompt()`
|
|
352
|
+
4. The agent corrects its decision based on human feedback
|
|
353
|
+
5. The workflow loops back to validation until approved
|
|
354
|
+
|
|
355
|
+
This creates a **continuous learning cycle** where agents improve through human guidance.
|
|
356
|
+
|
|
231
357
|
---
|
|
232
358
|
|
|
233
359
|
## š Examples
|
|
@@ -240,7 +366,6 @@ Comprehensive examples are organized in the `examples/` directory by complexity
|
|
|
240
366
|
|
|
241
367
|
- `01-simple-agent.ts` - Basic agent with tools and memory
|
|
242
368
|
- `02-memory-and-context.ts` - Conversational memory deep dive
|
|
243
|
-
- `03-langchain-native-hitl.ts` - LangChain's native HITL middleware
|
|
244
369
|
|
|
245
370
|
**2. Loopman Integration** (`examples/2-loopman-integration/`)
|
|
246
371
|
|
|
@@ -270,7 +395,7 @@ Comprehensive examples are organized in the `examples/` directory by complexity
|
|
|
270
395
|
```bash
|
|
271
396
|
# Basics
|
|
272
397
|
npx tsx examples/1-basics/01-simple-agent.ts
|
|
273
|
-
npx tsx examples/1-basics/
|
|
398
|
+
npx tsx examples/1-basics/02-memory-and-context.ts
|
|
274
399
|
|
|
275
400
|
# Loopman Integration
|
|
276
401
|
npx tsx examples/2-loopman-integration/01-middleware-basic.ts
|
|
@@ -290,112 +415,39 @@ npm run example:langgraph-full-state
|
|
|
290
415
|
|
|
291
416
|
See [Examples README](./examples/README.md) for detailed documentation and learning paths.
|
|
292
417
|
|
|
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
418
|
---
|
|
298
419
|
|
|
299
|
-
|
|
420
|
+
## š LangGraph Integration
|
|
300
421
|
|
|
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
|
|
422
|
+
The SDK provides complete LangGraph support with reusable nodes for building stateful validation workflows.
|
|
307
423
|
|
|
308
|
-
|
|
424
|
+
### Key Components
|
|
309
425
|
|
|
310
|
-
|
|
426
|
+
1. **Context Node** (`createLoopmanContextNode`): Loads guidelines and decision history
|
|
427
|
+
2. **Validation Node** (`createLoopmanValidationNode`): Sends actions for human approval and polls for decisions
|
|
428
|
+
3. **Conditional Edge** (`createLoopmanConditionalEdge`): Routes workflow based on human decisions
|
|
429
|
+
4. **Helper Functions** (`enrichSystemPrompt`): Injects context into agent prompts
|
|
311
430
|
|
|
312
|
-
|
|
431
|
+
### Complete Workflow Example
|
|
313
432
|
|
|
314
|
-
|
|
433
|
+
See the [Quick Start](#quick-start) section above for a complete LangGraph workflow example with validation nodes and conditional routing.
|
|
315
434
|
|
|
316
|
-
|
|
435
|
+
### Decision Routing & Feedback Loop
|
|
317
436
|
|
|
318
|
-
|
|
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
|
-
```
|
|
437
|
+
The conditional edge routes your workflow based on human decisions:
|
|
328
438
|
|
|
329
|
-
|
|
439
|
+
- **`execute`**: Human approved ā Continue to tool execution
|
|
440
|
+
- **`rejected`**: Human rejected ā End workflow
|
|
441
|
+
- **`retry`**: Human requested changes ā **Retry agent with feedback (FEEDBACK LOOP)** š
|
|
442
|
+
- **`timeout`**: No decision within timeout ā End workflow (or fallback)
|
|
443
|
+
- **`error`**: API error ā End workflow (or fallback)
|
|
330
444
|
|
|
331
|
-
|
|
332
|
-
import { loopmanMiddleware } from "./src/loopman-middleware";
|
|
445
|
+
**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.
|
|
333
446
|
|
|
334
|
-
|
|
335
|
-
// Required
|
|
336
|
-
apiKey: "your-loopman-api-key",
|
|
337
|
-
workflowId: "email-workflow",
|
|
338
|
-
|
|
339
|
-
// Optional
|
|
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
|
-
```
|
|
353
|
-
|
|
354
|
-
### Decision Flow (Automatic)
|
|
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
|
-
```
|
|
376
|
-
|
|
377
|
-
**Note:** Green boxes = Handled by middleware (transparent to your code)
|
|
447
|
+
### Running the Example
|
|
378
448
|
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
```typescript
|
|
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
|
-
}
|
|
393
|
-
|
|
394
|
-
// Reject
|
|
395
|
-
{
|
|
396
|
-
type: "reject",
|
|
397
|
-
message: "Reason for rejection"
|
|
398
|
-
}
|
|
449
|
+
```bash
|
|
450
|
+
npx tsx examples/5-langgraph-integration/loopman-validation-graph.ts
|
|
399
451
|
```
|
|
400
452
|
|
|
401
453
|
---
|
|
@@ -460,35 +512,57 @@ loopman-langchain-sdk-typescript/
|
|
|
460
512
|
|
|
461
513
|
## š API Reference
|
|
462
514
|
|
|
463
|
-
###
|
|
515
|
+
### LangGraph API
|
|
464
516
|
|
|
465
|
-
#### `
|
|
517
|
+
#### `createLoopmanContextNode(config)`
|
|
466
518
|
|
|
467
|
-
Creates a
|
|
519
|
+
Creates a LangGraph node that loads guidelines and decision history.
|
|
468
520
|
|
|
469
521
|
**Parameters:**
|
|
470
522
|
|
|
471
523
|
- `config.apiKey` (string, required): Loopman API key
|
|
472
524
|
- `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
|
|
525
|
+
- `config.category` (string, optional): Category filter for guidelines
|
|
478
526
|
- `config.debug` (boolean, optional): Enable debug logging
|
|
479
527
|
|
|
480
|
-
**Returns:**
|
|
528
|
+
**Returns:** LangGraph node function
|
|
481
529
|
|
|
482
|
-
|
|
530
|
+
#### `createLoopmanValidationNode(config)`
|
|
483
531
|
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
532
|
+
Creates a LangGraph node that handles human validation.
|
|
533
|
+
|
|
534
|
+
**Parameters:**
|
|
535
|
+
|
|
536
|
+
- `config.apiKey` (string, required): Loopman API key
|
|
537
|
+
- `config.workflowId` (string, required): Workflow identifier
|
|
538
|
+
- `config.timeout` (number, optional): Decision timeout in ms (default: 5 minutes)
|
|
539
|
+
- `config.pollingInterval` (number, optional): Polling interval in ms (default: 5 seconds)
|
|
540
|
+
- `config.debug` (boolean, optional): Enable debug logging
|
|
541
|
+
|
|
542
|
+
**Returns:** LangGraph node function
|
|
543
|
+
|
|
544
|
+
#### `createLoopmanConditionalEdge(config)`
|
|
545
|
+
|
|
546
|
+
Creates a conditional edge for routing based on validation results.
|
|
547
|
+
|
|
548
|
+
**Parameters:**
|
|
549
|
+
|
|
550
|
+
- `config.debug` (boolean, optional): Enable debug logging
|
|
551
|
+
|
|
552
|
+
**Returns:** Conditional edge function
|
|
553
|
+
|
|
554
|
+
#### `enrichSystemPrompt(basePrompt, context, options)`
|
|
555
|
+
|
|
556
|
+
Enriches a system prompt with Loopman context.
|
|
557
|
+
|
|
558
|
+
**Parameters:**
|
|
559
|
+
|
|
560
|
+
- `basePrompt` (string): Base system prompt
|
|
561
|
+
- `context.guidelines` (array, optional): Guidelines to inject
|
|
562
|
+
- `context.decisionContext` (array, optional): Decision history to inject
|
|
563
|
+
- `options.maxDecisions` (number, optional): Max number of decisions to include
|
|
564
|
+
|
|
565
|
+
**Returns:** Enriched system prompt string
|
|
492
566
|
|
|
493
567
|
### Loopman Agent API
|
|
494
568
|
|
|
@@ -530,8 +604,6 @@ const result = await agent.processWithHumanValidation({
|
|
|
530
604
|
});
|
|
531
605
|
```
|
|
532
606
|
|
|
533
|
-
See [Loopman Agent Guide](./docs/LOOPMAN_AGENT.md) for complete API documentation.
|
|
534
|
-
|
|
535
607
|
---
|
|
536
608
|
|
|
537
609
|
## š ļø Development
|
|
@@ -595,19 +667,6 @@ See `src/loopman-middleware.ts` for the complete implementation.
|
|
|
595
667
|
|
|
596
668
|
## š Related Resources
|
|
597
669
|
|
|
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
670
|
### LangChain Documentation
|
|
612
671
|
|
|
613
672
|
- [LangChain v1.0 Quickstart](https://docs.langchain.com/oss/javascript/langchain/quickstart)
|
|
@@ -617,9 +676,9 @@ See `src/loopman-middleware.ts` for the complete implementation.
|
|
|
617
676
|
|
|
618
677
|
### Loopman Platform
|
|
619
678
|
|
|
620
|
-
- [Loopman
|
|
621
|
-
- [Loopman Web App](
|
|
622
|
-
-
|
|
679
|
+
- [Loopman Website](https://loopman.ai) - Official website and documentation
|
|
680
|
+
- [Loopman Web App](https://app.loopman.ai) - Web interface for managing workflows
|
|
681
|
+
- Loopman Mobile App - Available on iOS and Android app stores
|
|
623
682
|
|
|
624
683
|
---
|
|
625
684
|
|
|
@@ -631,7 +690,7 @@ MPL-2.0 (Mozilla Public License 2.0). See `LICENSE`.
|
|
|
631
690
|
|
|
632
691
|
## š¤ Contributing
|
|
633
692
|
|
|
634
|
-
|
|
693
|
+
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
694
|
|
|
636
695
|
---
|
|
637
696
|
|
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.3\",\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.3\",\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.3\",\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.3",
|
|
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.3",
|
|
19
19
|
"dotenv": "^17.2.3",
|
|
20
20
|
"langchain": "^1.0.2",
|
|
21
21
|
"tsx": "^4.20.6",
|