@getzep/zep-cloud 2.4.0 → 2.6.0
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/api/resources/document/client/Client.d.ts +4 -4
- package/api/resources/document/client/Client.js +17 -17
- package/api/resources/graph/client/Client.d.ts +18 -1
- package/api/resources/graph/client/Client.js +82 -3
- package/api/resources/graph/client/requests/AddTripleRequest.d.ts +41 -0
- package/api/resources/graph/client/requests/AddTripleRequest.js +5 -0
- package/api/resources/graph/client/requests/GraphSearchQuery.d.ts +3 -1
- package/api/resources/graph/client/requests/index.d.ts +1 -0
- package/api/resources/graph/resources/edge/client/Client.d.ts +4 -4
- package/api/resources/graph/resources/edge/client/Client.js +8 -8
- package/api/resources/graph/resources/episode/client/Client.d.ts +4 -4
- package/api/resources/graph/resources/episode/client/Client.js +8 -8
- package/api/resources/graph/resources/node/client/Client.d.ts +3 -3
- package/api/resources/graph/resources/node/client/Client.js +6 -6
- package/api/resources/group/client/Client.d.ts +24 -9
- package/api/resources/group/client/Client.js +99 -14
- package/api/resources/group/client/requests/CreateGroupRequest.d.ts +0 -1
- package/api/resources/group/client/requests/GetGroupsOrderedRequest.d.ts +2 -2
- package/api/resources/group/client/requests/UpdateGroupRequest.d.ts +13 -0
- package/api/resources/group/client/requests/UpdateGroupRequest.js +5 -0
- package/api/resources/group/client/requests/index.d.ts +1 -0
- package/api/resources/memory/client/Client.d.ts +20 -22
- package/api/resources/memory/client/Client.js +42 -44
- package/api/resources/memory/client/requests/AddMemoryRequest.d.ts +8 -2
- package/api/resources/memory/client/requests/CreateSessionRequest.d.ts +2 -2
- package/api/resources/memory/client/requests/MemoryGetRequest.d.ts +1 -1
- package/api/resources/memory/client/requests/MemoryGetSessionFactsRequest.d.ts +1 -1
- package/api/resources/memory/client/requests/MemoryListSessionsRequest.d.ts +3 -3
- package/api/resources/memory/client/requests/ModelsMessageMetadataUpdate.d.ts +1 -1
- package/api/resources/memory/client/requests/SessionSearchQuery.d.ts +7 -7
- package/api/resources/memory/client/requests/UpdateSessionRequest.d.ts +1 -1
- package/api/resources/user/client/Client.d.ts +8 -8
- package/api/resources/user/client/Client.js +16 -16
- package/api/types/AddTripleResponse.d.ts +9 -0
- package/api/types/AddTripleResponse.js +5 -0
- package/api/types/ClassifySessionRequest.d.ts +2 -2
- package/api/types/EntityNode.d.ts +2 -0
- package/api/types/Fact.d.ts +1 -1
- package/api/types/Group.d.ts +1 -1
- package/api/types/Memory.d.ts +3 -9
- package/api/types/Message.d.ts +3 -3
- package/api/types/SearchFilters.d.ts +7 -0
- package/api/types/SearchFilters.js +5 -0
- package/api/types/Session.d.ts +4 -2
- package/api/types/User.d.ts +3 -0
- package/api/types/index.d.ts +2 -0
- package/api/types/index.js +2 -0
- package/dist/api/resources/document/client/Client.d.ts +4 -4
- package/dist/api/resources/document/client/Client.js +17 -17
- package/dist/api/resources/graph/client/Client.d.ts +18 -1
- package/dist/api/resources/graph/client/Client.js +82 -3
- package/dist/api/resources/graph/client/requests/AddTripleRequest.d.ts +41 -0
- package/dist/api/resources/graph/client/requests/AddTripleRequest.js +5 -0
- package/dist/api/resources/graph/client/requests/GraphSearchQuery.d.ts +3 -1
- package/dist/api/resources/graph/client/requests/index.d.ts +1 -0
- package/dist/api/resources/graph/resources/edge/client/Client.d.ts +4 -4
- package/dist/api/resources/graph/resources/edge/client/Client.js +8 -8
- package/dist/api/resources/graph/resources/episode/client/Client.d.ts +4 -4
- package/dist/api/resources/graph/resources/episode/client/Client.js +8 -8
- package/dist/api/resources/graph/resources/node/client/Client.d.ts +3 -3
- package/dist/api/resources/graph/resources/node/client/Client.js +6 -6
- package/dist/api/resources/group/client/Client.d.ts +24 -9
- package/dist/api/resources/group/client/Client.js +99 -14
- package/dist/api/resources/group/client/requests/CreateGroupRequest.d.ts +0 -1
- package/dist/api/resources/group/client/requests/GetGroupsOrderedRequest.d.ts +2 -2
- package/dist/api/resources/group/client/requests/UpdateGroupRequest.d.ts +13 -0
- package/dist/api/resources/group/client/requests/UpdateGroupRequest.js +5 -0
- package/dist/api/resources/group/client/requests/index.d.ts +1 -0
- package/dist/api/resources/memory/client/Client.d.ts +20 -22
- package/dist/api/resources/memory/client/Client.js +42 -44
- package/dist/api/resources/memory/client/requests/AddMemoryRequest.d.ts +8 -2
- package/dist/api/resources/memory/client/requests/CreateSessionRequest.d.ts +2 -2
- package/dist/api/resources/memory/client/requests/MemoryGetRequest.d.ts +1 -1
- package/dist/api/resources/memory/client/requests/MemoryGetSessionFactsRequest.d.ts +1 -1
- package/dist/api/resources/memory/client/requests/MemoryListSessionsRequest.d.ts +3 -3
- package/dist/api/resources/memory/client/requests/ModelsMessageMetadataUpdate.d.ts +1 -1
- package/dist/api/resources/memory/client/requests/SessionSearchQuery.d.ts +7 -7
- package/dist/api/resources/memory/client/requests/UpdateSessionRequest.d.ts +1 -1
- package/dist/api/resources/user/client/Client.d.ts +8 -8
- package/dist/api/resources/user/client/Client.js +16 -16
- package/dist/api/types/AddTripleResponse.d.ts +9 -0
- package/dist/api/types/AddTripleResponse.js +5 -0
- package/dist/api/types/ClassifySessionRequest.d.ts +2 -2
- package/dist/api/types/EntityNode.d.ts +2 -0
- package/dist/api/types/Fact.d.ts +1 -1
- package/dist/api/types/Group.d.ts +1 -1
- package/dist/api/types/Memory.d.ts +3 -9
- package/dist/api/types/Message.d.ts +3 -3
- package/dist/api/types/SearchFilters.d.ts +7 -0
- package/dist/api/types/SearchFilters.js +5 -0
- package/dist/api/types/Session.d.ts +4 -2
- package/dist/api/types/User.d.ts +3 -0
- package/dist/api/types/index.d.ts +2 -0
- package/dist/api/types/index.js +2 -0
- package/dist/serialization/resources/graph/client/requests/AddTripleRequest.d.ts +26 -0
- package/dist/serialization/resources/graph/client/requests/AddTripleRequest.js +57 -0
- package/dist/serialization/resources/graph/client/requests/GraphSearchQuery.d.ts +2 -0
- package/dist/serialization/resources/graph/client/requests/GraphSearchQuery.js +2 -0
- package/dist/serialization/resources/graph/client/requests/index.d.ts +1 -0
- package/dist/serialization/resources/graph/client/requests/index.js +3 -1
- package/dist/serialization/resources/group/client/requests/UpdateGroupRequest.d.ts +15 -0
- package/dist/serialization/resources/group/client/requests/UpdateGroupRequest.js +46 -0
- package/dist/serialization/resources/group/client/requests/index.d.ts +1 -0
- package/dist/serialization/resources/group/client/requests/index.js +3 -1
- package/dist/serialization/resources/memory/client/requests/AddMemoryRequest.d.ts +2 -0
- package/dist/serialization/resources/memory/client/requests/AddMemoryRequest.js +2 -0
- package/dist/serialization/types/AddTripleResponse.d.ts +16 -0
- package/dist/serialization/types/AddTripleResponse.js +47 -0
- package/dist/serialization/types/EntityNode.d.ts +1 -0
- package/dist/serialization/types/EntityNode.js +1 -0
- package/dist/serialization/types/SearchFilters.d.ts +12 -0
- package/dist/serialization/types/SearchFilters.js +43 -0
- package/dist/serialization/types/index.d.ts +2 -0
- package/dist/serialization/types/index.js +2 -0
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/examples/langgraph/.env.example +7 -0
- package/examples/langgraph/README.md +165 -0
- package/examples/langgraph/agent.ts +261 -0
- package/examples/langgraph/package-lock.json +1697 -0
- package/examples/langgraph/package.json +20 -0
- package/examples/langgraph/zep-memory.ts +271 -0
- package/package.json +1 -1
- package/reference.md +191 -68
- package/serialization/resources/graph/client/requests/AddTripleRequest.d.ts +26 -0
- package/serialization/resources/graph/client/requests/AddTripleRequest.js +57 -0
- package/serialization/resources/graph/client/requests/GraphSearchQuery.d.ts +2 -0
- package/serialization/resources/graph/client/requests/GraphSearchQuery.js +2 -0
- package/serialization/resources/graph/client/requests/index.d.ts +1 -0
- package/serialization/resources/graph/client/requests/index.js +3 -1
- package/serialization/resources/group/client/requests/UpdateGroupRequest.d.ts +15 -0
- package/serialization/resources/group/client/requests/UpdateGroupRequest.js +46 -0
- package/serialization/resources/group/client/requests/index.d.ts +1 -0
- package/serialization/resources/group/client/requests/index.js +3 -1
- package/serialization/resources/memory/client/requests/AddMemoryRequest.d.ts +2 -0
- package/serialization/resources/memory/client/requests/AddMemoryRequest.js +2 -0
- package/serialization/types/AddTripleResponse.d.ts +16 -0
- package/serialization/types/AddTripleResponse.js +47 -0
- package/serialization/types/EntityNode.d.ts +1 -0
- package/serialization/types/EntityNode.js +1 -0
- package/serialization/types/SearchFilters.d.ts +12 -0
- package/serialization/types/SearchFilters.js +43 -0
- package/serialization/types/index.d.ts +2 -0
- package/serialization/types/index.js +2 -0
- package/version.d.ts +1 -1
- package/version.js +1 -1
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* This file was auto-generated by Fern from our API Definition.
|
|
4
|
+
*/
|
|
5
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
6
|
+
if (k2 === undefined) k2 = k;
|
|
7
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
8
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
9
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
10
|
+
}
|
|
11
|
+
Object.defineProperty(o, k2, desc);
|
|
12
|
+
}) : (function(o, m, k, k2) {
|
|
13
|
+
if (k2 === undefined) k2 = k;
|
|
14
|
+
o[k2] = m[k];
|
|
15
|
+
}));
|
|
16
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
17
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
18
|
+
}) : function(o, v) {
|
|
19
|
+
o["default"] = v;
|
|
20
|
+
});
|
|
21
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
22
|
+
var ownKeys = function(o) {
|
|
23
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
24
|
+
var ar = [];
|
|
25
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
26
|
+
return ar;
|
|
27
|
+
};
|
|
28
|
+
return ownKeys(o);
|
|
29
|
+
};
|
|
30
|
+
return function (mod) {
|
|
31
|
+
if (mod && mod.__esModule) return mod;
|
|
32
|
+
var result = {};
|
|
33
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
34
|
+
__setModuleDefault(result, mod);
|
|
35
|
+
return result;
|
|
36
|
+
};
|
|
37
|
+
})();
|
|
38
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
39
|
+
exports.AddTripleResponse = void 0;
|
|
40
|
+
const core = __importStar(require("../../core"));
|
|
41
|
+
const EntityEdge_1 = require("./EntityEdge");
|
|
42
|
+
const EntityNode_1 = require("./EntityNode");
|
|
43
|
+
exports.AddTripleResponse = core.serialization.object({
|
|
44
|
+
edge: EntityEdge_1.EntityEdge.optional(),
|
|
45
|
+
sourceNode: core.serialization.property("source_node", EntityNode_1.EntityNode.optional()),
|
|
46
|
+
targetNode: core.serialization.property("target_node", EntityNode_1.EntityNode.optional()),
|
|
47
|
+
});
|
|
@@ -7,6 +7,7 @@ import * as core from "../../core";
|
|
|
7
7
|
export declare const EntityNode: core.serialization.ObjectSchema<serializers.EntityNode.Raw, Zep.EntityNode>;
|
|
8
8
|
export declare namespace EntityNode {
|
|
9
9
|
interface Raw {
|
|
10
|
+
attributes?: Record<string, unknown> | null;
|
|
10
11
|
created_at: string;
|
|
11
12
|
labels?: string[] | null;
|
|
12
13
|
name: string;
|
|
@@ -39,6 +39,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
39
39
|
exports.EntityNode = void 0;
|
|
40
40
|
const core = __importStar(require("../../core"));
|
|
41
41
|
exports.EntityNode = core.serialization.object({
|
|
42
|
+
attributes: core.serialization.record(core.serialization.string(), core.serialization.unknown()).optional(),
|
|
42
43
|
createdAt: core.serialization.property("created_at", core.serialization.string()),
|
|
43
44
|
labels: core.serialization.list(core.serialization.string()).optional(),
|
|
44
45
|
name: core.serialization.string(),
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* This file was auto-generated by Fern from our API Definition.
|
|
3
|
+
*/
|
|
4
|
+
import * as serializers from "../index";
|
|
5
|
+
import * as Zep from "../../api/index";
|
|
6
|
+
import * as core from "../../core";
|
|
7
|
+
export declare const SearchFilters: core.serialization.ObjectSchema<serializers.SearchFilters.Raw, Zep.SearchFilters>;
|
|
8
|
+
export declare namespace SearchFilters {
|
|
9
|
+
interface Raw {
|
|
10
|
+
node_labels?: string[] | null;
|
|
11
|
+
}
|
|
12
|
+
}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* This file was auto-generated by Fern from our API Definition.
|
|
4
|
+
*/
|
|
5
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
6
|
+
if (k2 === undefined) k2 = k;
|
|
7
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
8
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
9
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
10
|
+
}
|
|
11
|
+
Object.defineProperty(o, k2, desc);
|
|
12
|
+
}) : (function(o, m, k, k2) {
|
|
13
|
+
if (k2 === undefined) k2 = k;
|
|
14
|
+
o[k2] = m[k];
|
|
15
|
+
}));
|
|
16
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
17
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
18
|
+
}) : function(o, v) {
|
|
19
|
+
o["default"] = v;
|
|
20
|
+
});
|
|
21
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
22
|
+
var ownKeys = function(o) {
|
|
23
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
24
|
+
var ar = [];
|
|
25
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
26
|
+
return ar;
|
|
27
|
+
};
|
|
28
|
+
return ownKeys(o);
|
|
29
|
+
};
|
|
30
|
+
return function (mod) {
|
|
31
|
+
if (mod && mod.__esModule) return mod;
|
|
32
|
+
var result = {};
|
|
33
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
34
|
+
__setModuleDefault(result, mod);
|
|
35
|
+
return result;
|
|
36
|
+
};
|
|
37
|
+
})();
|
|
38
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
39
|
+
exports.SearchFilters = void 0;
|
|
40
|
+
const core = __importStar(require("../../core"));
|
|
41
|
+
exports.SearchFilters = core.serialization.object({
|
|
42
|
+
nodeLabels: core.serialization.property("node_labels", core.serialization.list(core.serialization.string()).optional()),
|
|
43
|
+
});
|
|
@@ -32,11 +32,13 @@ export * from "./SummaryListResponse";
|
|
|
32
32
|
export * from "./User";
|
|
33
33
|
export * from "./UserListResponse";
|
|
34
34
|
export * from "./UserNodeResponse";
|
|
35
|
+
export * from "./AddTripleResponse";
|
|
35
36
|
export * from "./EntityEdge";
|
|
36
37
|
export * from "./EntityNode";
|
|
37
38
|
export * from "./GraphSearchResults";
|
|
38
39
|
export * from "./GraphSearchScope";
|
|
39
40
|
export * from "./Reranker";
|
|
41
|
+
export * from "./SearchFilters";
|
|
40
42
|
export * from "./ClassifySessionRequest";
|
|
41
43
|
export * from "./CreateDocumentRequest";
|
|
42
44
|
export * from "./FactRatingExamples";
|
|
@@ -48,11 +48,13 @@ __exportStar(require("./SummaryListResponse"), exports);
|
|
|
48
48
|
__exportStar(require("./User"), exports);
|
|
49
49
|
__exportStar(require("./UserListResponse"), exports);
|
|
50
50
|
__exportStar(require("./UserNodeResponse"), exports);
|
|
51
|
+
__exportStar(require("./AddTripleResponse"), exports);
|
|
51
52
|
__exportStar(require("./EntityEdge"), exports);
|
|
52
53
|
__exportStar(require("./EntityNode"), exports);
|
|
53
54
|
__exportStar(require("./GraphSearchResults"), exports);
|
|
54
55
|
__exportStar(require("./GraphSearchScope"), exports);
|
|
55
56
|
__exportStar(require("./Reranker"), exports);
|
|
57
|
+
__exportStar(require("./SearchFilters"), exports);
|
|
56
58
|
__exportStar(require("./ClassifySessionRequest"), exports);
|
|
57
59
|
__exportStar(require("./CreateDocumentRequest"), exports);
|
|
58
60
|
__exportStar(require("./FactRatingExamples"), exports);
|
package/dist/version.d.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export declare const SDK_VERSION = "2.
|
|
1
|
+
export declare const SDK_VERSION = "2.6.0";
|
package/dist/version.js
CHANGED
|
@@ -0,0 +1,165 @@
|
|
|
1
|
+
# LangGraph CLI Agent
|
|
2
|
+
|
|
3
|
+
This is a simple CLI agent built with LangGraph.js that can answer questions and use tools to search for information. It also integrates with Zep for memory persistence.
|
|
4
|
+
|
|
5
|
+
## Prerequisites
|
|
6
|
+
|
|
7
|
+
- Node.js 18+ installed
|
|
8
|
+
- OpenAI API key
|
|
9
|
+
- Tavily API key (for search functionality)
|
|
10
|
+
- Zep API key (for memory persistence)
|
|
11
|
+
|
|
12
|
+
## Setup
|
|
13
|
+
|
|
14
|
+
1. Install dependencies:
|
|
15
|
+
|
|
16
|
+
```bash
|
|
17
|
+
npm install
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
2. Create a `.env` file in this directory with your API keys:
|
|
21
|
+
|
|
22
|
+
```
|
|
23
|
+
OPENAI_API_KEY=your_openai_api_key_here
|
|
24
|
+
TAVILY_API_KEY=your_tavily_api_key_here
|
|
25
|
+
ZEP_API_KEY=your_zep_api_key_here
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
## Running the Agent
|
|
29
|
+
|
|
30
|
+
To start the CLI agent, run:
|
|
31
|
+
|
|
32
|
+
```bash
|
|
33
|
+
npm start
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
### Command-Line Options
|
|
37
|
+
|
|
38
|
+
The agent supports various command-line options through Commander.js:
|
|
39
|
+
|
|
40
|
+
```bash
|
|
41
|
+
# Get help
|
|
42
|
+
npm start -- --help
|
|
43
|
+
|
|
44
|
+
# Basic usage with user ID
|
|
45
|
+
npm start -- --userId john_doe
|
|
46
|
+
|
|
47
|
+
# Using kebab-case format
|
|
48
|
+
npm start -- --user-id john_doe --session-id vacation_planning
|
|
49
|
+
|
|
50
|
+
# Customize the system message
|
|
51
|
+
npm start -- --system-message "You are a travel assistant helping with vacation planning."
|
|
52
|
+
|
|
53
|
+
# Enable debug mode
|
|
54
|
+
npm start -- --debug
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
Available options:
|
|
58
|
+
|
|
59
|
+
| Option | Description |
|
|
60
|
+
| ---------------------------- | ------------------------------------------ |
|
|
61
|
+
| `--userId <id>` | User ID to associate with the conversation |
|
|
62
|
+
| `--user-id <id>` | Alternative format for user ID |
|
|
63
|
+
| `--sessionId <id>` | Session ID for the conversation |
|
|
64
|
+
| `--session-id <id>` | Alternative format for session ID |
|
|
65
|
+
| `--system-message <message>` | Custom system message to use |
|
|
66
|
+
| `--debug` | Enable debug mode with additional logging |
|
|
67
|
+
| `--help` | Display help information |
|
|
68
|
+
| `--version` | Display version information |
|
|
69
|
+
|
|
70
|
+
### Memory Features
|
|
71
|
+
|
|
72
|
+
Using the user ID and session ID options allows you to:
|
|
73
|
+
|
|
74
|
+
- **Maintain separate conversation histories** for different users
|
|
75
|
+
- **Continue specific conversations** by using the same session ID
|
|
76
|
+
- **Group related conversations** under the same user ID
|
|
77
|
+
- **Switch between different contexts** by changing the session ID
|
|
78
|
+
|
|
79
|
+
The agent will automatically create users and sessions in Zep if they don't exist, and will load previous conversation history when available.
|
|
80
|
+
|
|
81
|
+
## Features
|
|
82
|
+
|
|
83
|
+
This will launch an interactive CLI where you can chat with the agent. Type your questions and the agent will respond. The agent can:
|
|
84
|
+
|
|
85
|
+
- Answer general knowledge questions
|
|
86
|
+
- Search the web for information using Tavily
|
|
87
|
+
- Maintain context throughout the conversation
|
|
88
|
+
- Persist conversation history using Zep memory
|
|
89
|
+
- Retrieve past conversations when restarted
|
|
90
|
+
- Associate conversations with specific users
|
|
91
|
+
- Continue conversations across different sessions
|
|
92
|
+
- Use custom system messages
|
|
93
|
+
|
|
94
|
+
Type `exit` to quit the application.
|
|
95
|
+
|
|
96
|
+
## How It Works
|
|
97
|
+
|
|
98
|
+
This agent is built using LangGraph.js, which allows for creating stateful, multi-step AI workflows as graphs. The agent:
|
|
99
|
+
|
|
100
|
+
1. Takes user input
|
|
101
|
+
2. Processes it through an LLM (OpenAI)
|
|
102
|
+
3. Decides whether to use tools or respond directly
|
|
103
|
+
4. If tools are needed, executes them and returns to the LLM
|
|
104
|
+
5. Returns the final response to the user
|
|
105
|
+
6. Persists all messages to Zep memory (if configured)
|
|
106
|
+
|
|
107
|
+
The graph maintains state between interactions, allowing for conversational context to be preserved. Additionally, the Zep memory integration provides long-term persistence of conversation history.
|
|
108
|
+
|
|
109
|
+
## Memory Integration
|
|
110
|
+
|
|
111
|
+
The agent uses Zep for memory persistence. When a Zep API key is provided, the agent will:
|
|
112
|
+
|
|
113
|
+
1. Create a new session in Zep (or use an existing one)
|
|
114
|
+
2. Store all user and AI messages in Zep memory
|
|
115
|
+
3. Maintain conversation history across restarts
|
|
116
|
+
4. Load previous messages when restarted
|
|
117
|
+
5. Provide context to the agent about the previous conversation
|
|
118
|
+
|
|
119
|
+
### User and Session Management
|
|
120
|
+
|
|
121
|
+
The agent supports specifying a user ID and session ID via command-line arguments:
|
|
122
|
+
|
|
123
|
+
- **User ID**: Associates conversations with a specific user in Zep
|
|
124
|
+
- **Session ID**: Uses a specific session ID for the conversation
|
|
125
|
+
|
|
126
|
+
This allows for powerful use cases such as:
|
|
127
|
+
|
|
128
|
+
- **Multi-user support**: Different users can have their own conversation histories
|
|
129
|
+
- **Topic-based sessions**: Create different sessions for different topics (e.g., "travel_planning", "tech_support")
|
|
130
|
+
- **Conversation continuity**: Resume specific conversations by using the same session ID
|
|
131
|
+
- **Organizational structure**: Group related conversations under the same user ID
|
|
132
|
+
- **A/B testing**: Compare different conversation flows by using different session IDs
|
|
133
|
+
|
|
134
|
+
### Advanced Memory Features
|
|
135
|
+
|
|
136
|
+
The Zep memory integration includes several advanced features:
|
|
137
|
+
|
|
138
|
+
- **User Management**: Creates and manages users associated with conversations
|
|
139
|
+
- **Session Management**: Creates and retrieves sessions for persistent conversations
|
|
140
|
+
- **Message Retrieval**: Loads previous messages when the agent is restarted
|
|
141
|
+
- **Memory Search**: Can search for relevant messages based on semantic similarity
|
|
142
|
+
- **Context Retrieval**: Can retrieve context information about the conversation
|
|
143
|
+
|
|
144
|
+
This allows the agent to maintain context over long periods and provide more personalized responses based on past interactions.
|
|
145
|
+
|
|
146
|
+
## Customization
|
|
147
|
+
|
|
148
|
+
You can modify `agent.ts` to:
|
|
149
|
+
|
|
150
|
+
- Change the LLM model
|
|
151
|
+
- Add additional tools
|
|
152
|
+
- Adjust the graph structure
|
|
153
|
+
- Customize the CLI interface
|
|
154
|
+
- Configure memory settings
|
|
155
|
+
|
|
156
|
+
The `zep-memory.ts` file contains the Zep memory integration and can be customized to:
|
|
157
|
+
|
|
158
|
+
- Change how messages are stored and retrieved
|
|
159
|
+
- Modify user and session management
|
|
160
|
+
- Add additional memory features
|
|
161
|
+
- Customize message conversion between LangChain and Zep formats
|
|
162
|
+
|
|
163
|
+
## License
|
|
164
|
+
|
|
165
|
+
MIT
|
|
@@ -0,0 +1,261 @@
|
|
|
1
|
+
// agent.ts
|
|
2
|
+
import dotenv from "dotenv";
|
|
3
|
+
|
|
4
|
+
// Load environment variables from .env file
|
|
5
|
+
dotenv.config();
|
|
6
|
+
|
|
7
|
+
import { TavilySearchResults } from "@langchain/community/tools/tavily_search";
|
|
8
|
+
import { ChatOpenAI } from "@langchain/openai";
|
|
9
|
+
import { HumanMessage, AIMessage, BaseMessage, SystemMessage } from "@langchain/core/messages";
|
|
10
|
+
import { ToolNode } from "@langchain/langgraph/prebuilt";
|
|
11
|
+
import { StateGraph, MessagesAnnotation } from "@langchain/langgraph";
|
|
12
|
+
import { fileURLToPath } from "url";
|
|
13
|
+
import path from "path";
|
|
14
|
+
import { Command } from "commander";
|
|
15
|
+
import { ZepMemory } from "./zep-memory";
|
|
16
|
+
|
|
17
|
+
// Define the tools for the agent to use
|
|
18
|
+
const tools = [new TavilySearchResults({ maxResults: 3 })];
|
|
19
|
+
const toolNode = new ToolNode(tools);
|
|
20
|
+
|
|
21
|
+
// Create a model and give it access to the tools
|
|
22
|
+
const model = new ChatOpenAI({
|
|
23
|
+
model: "gpt-4o-mini",
|
|
24
|
+
temperature: 0,
|
|
25
|
+
}).bindTools(tools);
|
|
26
|
+
|
|
27
|
+
// Define the function that determines whether to continue or not
|
|
28
|
+
function shouldContinue({ messages }: typeof MessagesAnnotation.State) {
|
|
29
|
+
const lastMessage = messages[messages.length - 1] as AIMessage;
|
|
30
|
+
|
|
31
|
+
// If the LLM makes a tool call, then we route to the "tools" node
|
|
32
|
+
if (lastMessage.tool_calls?.length) {
|
|
33
|
+
return "tools";
|
|
34
|
+
}
|
|
35
|
+
// Otherwise, we stop (reply to the user) using the special "__end__" node
|
|
36
|
+
return "__end__";
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
// Define the function that calls the model
|
|
40
|
+
async function callModel(state: typeof MessagesAnnotation.State) {
|
|
41
|
+
const response = await model.invoke(state.messages);
|
|
42
|
+
return { messages: [...state.messages, response] };
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
// Define the workflow as a graph
|
|
46
|
+
const workflow = new StateGraph(MessagesAnnotation)
|
|
47
|
+
.addNode("agent", callModel)
|
|
48
|
+
.addNode("tools", toolNode)
|
|
49
|
+
.addEdge("__start__", "agent")
|
|
50
|
+
.addConditionalEdges("agent", shouldContinue, ["tools", "__end__"])
|
|
51
|
+
.addEdge("tools", "agent");
|
|
52
|
+
|
|
53
|
+
// Compile the graph
|
|
54
|
+
export const graph = workflow.compile();
|
|
55
|
+
|
|
56
|
+
// Parse command line arguments using Commander
|
|
57
|
+
function parseCommandLineArgs() {
|
|
58
|
+
const program = new Command();
|
|
59
|
+
|
|
60
|
+
program
|
|
61
|
+
.name("langgraph-agent")
|
|
62
|
+
.description("LangGraph CLI Agent with Zep memory integration")
|
|
63
|
+
.version("1.0.0")
|
|
64
|
+
.option("--userId <id>", "User ID to associate with the conversation")
|
|
65
|
+
.option("--user-id <id>", "User ID to associate with the conversation (alternative format)")
|
|
66
|
+
.option("--sessionId <id>", "Session ID for the conversation")
|
|
67
|
+
.option("--session-id <id>", "Session ID for the conversation (alternative format)")
|
|
68
|
+
.option("--system-message <message>", "Custom system message to use")
|
|
69
|
+
.option("--debug", "Enable debug mode with additional logging");
|
|
70
|
+
|
|
71
|
+
program.parse();
|
|
72
|
+
|
|
73
|
+
const options = program.opts();
|
|
74
|
+
|
|
75
|
+
// Handle alternative formats and naming
|
|
76
|
+
return {
|
|
77
|
+
userId: options.userId,
|
|
78
|
+
sessionId: options.sessionId,
|
|
79
|
+
systemMessage: options.systemMessage || "You are a helpful assistant. Answer the user's questions to the best of your ability.",
|
|
80
|
+
debug: !!options.debug
|
|
81
|
+
};
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
// Check if this file is being run directly
|
|
85
|
+
const isMainModule = () => {
|
|
86
|
+
if (typeof require !== 'undefined' && require.main === module) {
|
|
87
|
+
return true;
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
if (import.meta.url) {
|
|
91
|
+
try {
|
|
92
|
+
const currentFilePath = fileURLToPath(import.meta.url);
|
|
93
|
+
const currentFileName = path.basename(currentFilePath);
|
|
94
|
+
// Check if this script was run directly with node/tsx
|
|
95
|
+
return process.argv[1] && process.argv[1].endsWith(currentFileName);
|
|
96
|
+
} catch (e) {
|
|
97
|
+
return false;
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
return false;
|
|
102
|
+
};
|
|
103
|
+
|
|
104
|
+
// Parse command line arguments once and store the result
|
|
105
|
+
const args = isMainModule() ? parseCommandLineArgs() : {
|
|
106
|
+
userId: undefined,
|
|
107
|
+
sessionId: undefined,
|
|
108
|
+
systemMessage: "You are a helpful assistant. Answer the user's questions to the best of your ability.",
|
|
109
|
+
debug: false
|
|
110
|
+
};
|
|
111
|
+
|
|
112
|
+
// Initialize Zep memory if API key is available
|
|
113
|
+
let zepMemory: ZepMemory | undefined;
|
|
114
|
+
if (process.env.ZEP_API_KEY) {
|
|
115
|
+
zepMemory = new ZepMemory(process.env.ZEP_API_KEY, args.sessionId, args.userId);
|
|
116
|
+
|
|
117
|
+
if (args.debug) {
|
|
118
|
+
console.log("Zep memory initialized with session ID:", zepMemory.getSessionId());
|
|
119
|
+
if (args.userId) {
|
|
120
|
+
console.log("Using user ID:", args.userId);
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
// CLI interface
|
|
126
|
+
if (isMainModule()) {
|
|
127
|
+
// This will run when the script is executed directly
|
|
128
|
+
const runCLI = async () => {
|
|
129
|
+
const systemMessage = args.systemMessage;
|
|
130
|
+
|
|
131
|
+
console.log("🦜🔗 LangGraph Agent CLI");
|
|
132
|
+
if (args.userId) {
|
|
133
|
+
console.log(`User ID: ${args.userId}`);
|
|
134
|
+
}
|
|
135
|
+
if (args.sessionId) {
|
|
136
|
+
console.log(`Session ID: ${args.sessionId}`);
|
|
137
|
+
}
|
|
138
|
+
console.log("Type 'exit' to quit the application");
|
|
139
|
+
console.log("------------------------------");
|
|
140
|
+
|
|
141
|
+
// Create a readline interface
|
|
142
|
+
const readline = await import("readline");
|
|
143
|
+
const rl = readline.createInterface({
|
|
144
|
+
input: process.stdin,
|
|
145
|
+
output: process.stdout,
|
|
146
|
+
});
|
|
147
|
+
|
|
148
|
+
// Create a new chat session
|
|
149
|
+
const config = { configurable: { sessionId: args.sessionId || "cli-session" } };
|
|
150
|
+
let state = { messages: [] as BaseMessage[] };
|
|
151
|
+
|
|
152
|
+
// Initialize Zep memory if available
|
|
153
|
+
if (zepMemory) {
|
|
154
|
+
try {
|
|
155
|
+
await zepMemory.initialize(args.userId);
|
|
156
|
+
console.log("Connected to Zep memory service");
|
|
157
|
+
|
|
158
|
+
// Try to load previous messages from Zep memory
|
|
159
|
+
try {
|
|
160
|
+
const previousMessages = await zepMemory.getMessages(10);
|
|
161
|
+
if (previousMessages.length > 0) {
|
|
162
|
+
state.messages = previousMessages;
|
|
163
|
+
console.log(`Loaded ${previousMessages.length} messages from previous conversation`);
|
|
164
|
+
}
|
|
165
|
+
} catch (error) {
|
|
166
|
+
console.error("Failed to load previous messages:", error);
|
|
167
|
+
console.log("Starting a new conversation");
|
|
168
|
+
}
|
|
169
|
+
} catch (error) {
|
|
170
|
+
console.error("Failed to initialize Zep memory:", error);
|
|
171
|
+
console.log("Continuing without memory persistence");
|
|
172
|
+
zepMemory = undefined;
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
const askQuestion = () => {
|
|
177
|
+
rl.question("\nYou: ", async (input) => {
|
|
178
|
+
if (input.toLowerCase() === "exit") {
|
|
179
|
+
console.log("Goodbye!");
|
|
180
|
+
rl.close();
|
|
181
|
+
return;
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
// Add the user's message to the state
|
|
185
|
+
const userMessage = new HumanMessage(input);
|
|
186
|
+
let systemMessageWithContext = systemMessage;
|
|
187
|
+
|
|
188
|
+
// Persist user message to Zep memory if available
|
|
189
|
+
let context: string | undefined;
|
|
190
|
+
if (zepMemory) {
|
|
191
|
+
try {
|
|
192
|
+
// Add the user message to Zep memory and get the context, if available
|
|
193
|
+
context = await zepMemory.addMessage(userMessage, true);
|
|
194
|
+
} catch (error) {
|
|
195
|
+
console.error("Failed to persist user message to Zep memory:", error);
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
try {
|
|
199
|
+
if (args.debug) {
|
|
200
|
+
console.log(context);
|
|
201
|
+
}
|
|
202
|
+
if (context) {
|
|
203
|
+
systemMessageWithContext = systemMessage + "\n" + context;
|
|
204
|
+
}
|
|
205
|
+
} catch (error) {
|
|
206
|
+
console.error("Failed to get memory with context:", error);
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
// Get the last 5 messages from the current state (excluding any previous system messages)
|
|
211
|
+
const previousMessages = state.messages
|
|
212
|
+
.filter(msg => !(msg instanceof SystemMessage))
|
|
213
|
+
.slice(-5);
|
|
214
|
+
|
|
215
|
+
// Create new state with system message at the beginning followed by the history messages
|
|
216
|
+
state.messages = [
|
|
217
|
+
new SystemMessage(systemMessageWithContext),
|
|
218
|
+
...previousMessages,
|
|
219
|
+
userMessage
|
|
220
|
+
];
|
|
221
|
+
|
|
222
|
+
try {
|
|
223
|
+
// Process the input through the graph
|
|
224
|
+
const result = await graph.invoke(state, config);
|
|
225
|
+
|
|
226
|
+
// Extract the AI's response using instanceof instead of _getType()
|
|
227
|
+
const aiMessages = result.messages.filter((msg) => msg instanceof AIMessage);
|
|
228
|
+
const lastAIMessage = aiMessages[aiMessages.length - 1] as AIMessage;
|
|
229
|
+
|
|
230
|
+
console.log(`\nAI: ${lastAIMessage.content}`);
|
|
231
|
+
|
|
232
|
+
// Persist AI message to Zep memory if available
|
|
233
|
+
if (zepMemory) {
|
|
234
|
+
try {
|
|
235
|
+
await zepMemory.addMessage(lastAIMessage);
|
|
236
|
+
} catch (error) {
|
|
237
|
+
console.error("Failed to persist AI message to Zep memory:", error);
|
|
238
|
+
}
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
// Update the state for the next interaction
|
|
242
|
+
// We don't want to completely replace the state, just update the messages
|
|
243
|
+
// to maintain our structure with the system message at the beginning
|
|
244
|
+
const resultMessages = result.messages.filter(msg => !(msg instanceof SystemMessage));
|
|
245
|
+
state = {
|
|
246
|
+
messages: resultMessages
|
|
247
|
+
};
|
|
248
|
+
} catch (error) {
|
|
249
|
+
console.error("Error:", error);
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
// Ask for the next input
|
|
253
|
+
askQuestion();
|
|
254
|
+
});
|
|
255
|
+
};
|
|
256
|
+
|
|
257
|
+
askQuestion();
|
|
258
|
+
};
|
|
259
|
+
|
|
260
|
+
runCLI().catch(console.error);
|
|
261
|
+
}
|