@ainetwork/adk-provider-memory-mongodb 0.1.1 → 0.1.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/implements/base.memory.ts +52 -0
- package/implements/intent.memory.ts +56 -0
- package/implements/session.memory.ts +103 -0
- package/index.ts +2 -107
- package/models/chats.model.ts +38 -9
- package/models/intent.model.ts +32 -0
- package/package.json +3 -3
- package/models/intentTriggeringInfos.model.ts +0 -50
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import { IMemory } from "node_modules/@ainetwork/adk/dist/esm/modules/memory/base.memory";
|
|
2
|
+
import mongoose, { Mongoose } from "mongoose";
|
|
3
|
+
import { loggers } from "@ainetwork/adk/utils/logger";
|
|
4
|
+
|
|
5
|
+
export class MongoDBMemory implements IMemory {
|
|
6
|
+
private _isConnected: boolean = false;
|
|
7
|
+
private _uri: string;
|
|
8
|
+
private _mongoose: Mongoose;
|
|
9
|
+
|
|
10
|
+
constructor(uri: string) {
|
|
11
|
+
this._uri = uri;
|
|
12
|
+
this._mongoose = new Mongoose();
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
public getInstance(): Mongoose {
|
|
16
|
+
return this._mongoose;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
public async connect(): Promise<void> {
|
|
20
|
+
if (this._isConnected) {
|
|
21
|
+
return;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
try {
|
|
25
|
+
await this._mongoose.connect(this._uri);
|
|
26
|
+
this._isConnected = true;
|
|
27
|
+
loggers.agent.info("MongoDB connected successfully");
|
|
28
|
+
} catch (error) {
|
|
29
|
+
loggers.agent.error("Failed to connect to MongoDB:", error);
|
|
30
|
+
throw error;
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
public async disconnect(): Promise<void> {
|
|
35
|
+
if (!this.isConnected) {
|
|
36
|
+
return;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
try {
|
|
40
|
+
await this._mongoose?.disconnect();
|
|
41
|
+
this._isConnected = false;
|
|
42
|
+
loggers.agent.info("MongoDB disconnected successfully");
|
|
43
|
+
} catch (error) {
|
|
44
|
+
loggers.agent.error("Failed to disconnect from MongoDB:", error);
|
|
45
|
+
throw error;
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
public isConnected(): boolean {
|
|
50
|
+
return this._isConnected;
|
|
51
|
+
}
|
|
52
|
+
}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import { randomUUID } from "node:crypto";
|
|
2
|
+
import type { Intent } from "@ainetwork/adk/types/memory";
|
|
3
|
+
import { IIntentMemory } from "@ainetwork/adk/modules";
|
|
4
|
+
import { MongoDBMemory } from "./base.memory";
|
|
5
|
+
import { IntentModel } from "../models/intent.model";
|
|
6
|
+
|
|
7
|
+
export class MongoDBIntent extends MongoDBMemory implements IIntentMemory {
|
|
8
|
+
public async getIntent(intentId: string): Promise<Intent | undefined> {
|
|
9
|
+
const intent = await IntentModel.findById(intentId);
|
|
10
|
+
if (intent) {
|
|
11
|
+
return {
|
|
12
|
+
name: intent.name,
|
|
13
|
+
description: intent.description,
|
|
14
|
+
prompt: intent.prompt,
|
|
15
|
+
llm: intent.llm,
|
|
16
|
+
} as Intent;
|
|
17
|
+
}
|
|
18
|
+
return undefined;
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
public async saveIntent(intent: Intent): Promise<void> {
|
|
22
|
+
const newId = randomUUID();
|
|
23
|
+
await IntentModel.create({
|
|
24
|
+
_id: newId,
|
|
25
|
+
name: intent.name,
|
|
26
|
+
description: intent.description,
|
|
27
|
+
prompt: intent.prompt,
|
|
28
|
+
llm: intent.llm,
|
|
29
|
+
});
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
public async updateIntent(intentId: string, intent: Intent): Promise<void> {
|
|
33
|
+
await IntentModel.updateOne({
|
|
34
|
+
_id: intentId,
|
|
35
|
+
},{
|
|
36
|
+
name: intent.name,
|
|
37
|
+
description: intent.description,
|
|
38
|
+
prompt: intent.prompt,
|
|
39
|
+
llm: intent.llm,
|
|
40
|
+
});
|
|
41
|
+
};
|
|
42
|
+
|
|
43
|
+
public async deleteIntent(intentId: string): Promise<void> {
|
|
44
|
+
await IntentModel.deleteOne({ _id: intentId });
|
|
45
|
+
};
|
|
46
|
+
|
|
47
|
+
public async listIntents(): Promise<Intent[]> {
|
|
48
|
+
const intents = await IntentModel.find();
|
|
49
|
+
return intents.map(intent => ({
|
|
50
|
+
name: intent.name,
|
|
51
|
+
description: intent.description,
|
|
52
|
+
prompt: intent.prompt,
|
|
53
|
+
llm: intent.llm,
|
|
54
|
+
} as Intent));
|
|
55
|
+
};
|
|
56
|
+
}
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
import { randomUUID } from "node:crypto";
|
|
2
|
+
import type { ChatObject, SessionMetadata, SessionObject } from "@ainetwork/adk/types/memory";
|
|
3
|
+
import { ISessionMemory } from "@ainetwork/adk/modules";
|
|
4
|
+
import { MongoDBMemory } from "./base.memory";
|
|
5
|
+
import {
|
|
6
|
+
ChatDocument,
|
|
7
|
+
ChatRole,
|
|
8
|
+
ChatObjectSchema,
|
|
9
|
+
SessionObjectSchema,
|
|
10
|
+
SessionDocument
|
|
11
|
+
} from "../models/chats.model";
|
|
12
|
+
import { loggers } from "@ainetwork/adk/utils/logger";
|
|
13
|
+
import { Model } from "mongoose";
|
|
14
|
+
|
|
15
|
+
export class MongoDBSession extends MongoDBMemory implements ISessionMemory {
|
|
16
|
+
private chatModel: Model<ChatDocument>;
|
|
17
|
+
private sessionModel: Model<SessionDocument>;
|
|
18
|
+
|
|
19
|
+
constructor(uri: string) {
|
|
20
|
+
super(uri);
|
|
21
|
+
const _mongoose = super.getInstance();
|
|
22
|
+
this.chatModel = _mongoose.model<ChatDocument>("Chat", ChatObjectSchema);
|
|
23
|
+
this.sessionModel = _mongoose.model<SessionDocument>("Session", SessionObjectSchema);
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
public async getSession(sessionId: string, userId?: string): Promise<SessionObject | undefined> {
|
|
27
|
+
const chats = await this.chatModel.find({ sessionId }).sort({
|
|
28
|
+
timestamp: 1,
|
|
29
|
+
});
|
|
30
|
+
|
|
31
|
+
loggers.agent.debug(`Found ${chats.length} chats for session ${sessionId}`);
|
|
32
|
+
|
|
33
|
+
const sessionObject: SessionObject = { chats: {} };
|
|
34
|
+
chats.forEach((chat: ChatDocument) => {
|
|
35
|
+
const chatId = chat._id?.toString() || chat.id;
|
|
36
|
+
sessionObject.chats[chatId] = {
|
|
37
|
+
role: chat.role as ChatRole,
|
|
38
|
+
content: chat.content,
|
|
39
|
+
timestamp: chat.timestamp,
|
|
40
|
+
metadata: chat.metadata,
|
|
41
|
+
};
|
|
42
|
+
});
|
|
43
|
+
|
|
44
|
+
return sessionObject;
|
|
45
|
+
};
|
|
46
|
+
|
|
47
|
+
public async createSession(userId: string, sessionId: string): Promise<void> {
|
|
48
|
+
await this.sessionModel.create({
|
|
49
|
+
sessionId,
|
|
50
|
+
userId,
|
|
51
|
+
updated_at: Date.now(),
|
|
52
|
+
created_at: Date.now(),
|
|
53
|
+
});
|
|
54
|
+
};
|
|
55
|
+
|
|
56
|
+
public async addChatToSession(userId: string, sessionId: string, chat: ChatObject): Promise<void> {
|
|
57
|
+
const newId = randomUUID();
|
|
58
|
+
const session = await this.sessionModel.findOne({ sessionId, userId });
|
|
59
|
+
if (!session) {
|
|
60
|
+
await this.createSession(userId, sessionId);
|
|
61
|
+
} else {
|
|
62
|
+
await this.sessionModel.updateOne({ sessionId, userId }, {
|
|
63
|
+
updated_at: Date.now(),
|
|
64
|
+
});
|
|
65
|
+
}
|
|
66
|
+
await this.chatModel.create({
|
|
67
|
+
sessionId,
|
|
68
|
+
chatId: newId,
|
|
69
|
+
userId,
|
|
70
|
+
role: chat.role,
|
|
71
|
+
content: chat.content,
|
|
72
|
+
timestamp: chat.timestamp,
|
|
73
|
+
metadata: chat.metadata,
|
|
74
|
+
});
|
|
75
|
+
};
|
|
76
|
+
|
|
77
|
+
public async deleteSession(userId: string, sessionId: string): Promise<void> {
|
|
78
|
+
const chats = await this.chatModel.find({ userId, sessionId }).sort({
|
|
79
|
+
timestamp: 1,
|
|
80
|
+
});
|
|
81
|
+
|
|
82
|
+
chats?.forEach((chat: ChatDocument) => {
|
|
83
|
+
chat.deleteOne();
|
|
84
|
+
});
|
|
85
|
+
|
|
86
|
+
const session = await this.sessionModel.findOne({ sessionId, userId });
|
|
87
|
+
session?.deleteOne();
|
|
88
|
+
};
|
|
89
|
+
|
|
90
|
+
public async listSessions(userId: string): Promise<SessionMetadata[]> {
|
|
91
|
+
const sessions = await this.sessionModel.find({ userId }).sort({
|
|
92
|
+
updated_at: -1,
|
|
93
|
+
});
|
|
94
|
+
const data: SessionMetadata[] = sessions.map((session: SessionDocument) => {
|
|
95
|
+
return {
|
|
96
|
+
sessionId: session.sessionId,
|
|
97
|
+
title: session.title,
|
|
98
|
+
updatedAt: session.updated_at
|
|
99
|
+
} as SessionMetadata;
|
|
100
|
+
})
|
|
101
|
+
return data;
|
|
102
|
+
};
|
|
103
|
+
}
|
package/index.ts
CHANGED
|
@@ -1,107 +1,2 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
import { loggers } from "@ainetwork/adk/utils/logger";
|
|
4
|
-
import mongoose from "mongoose";
|
|
5
|
-
import {
|
|
6
|
-
type ChatDocument,
|
|
7
|
-
ChatModel,
|
|
8
|
-
ChatRole,
|
|
9
|
-
} from "./models/chats.model";
|
|
10
|
-
|
|
11
|
-
export class MongoDBMemory extends BaseMemory {
|
|
12
|
-
private isConnected = false;
|
|
13
|
-
|
|
14
|
-
constructor(uri: string) {
|
|
15
|
-
super();
|
|
16
|
-
this.connect(uri);
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
public async connect(uri: string): Promise<void> {
|
|
20
|
-
if (this.isConnected) {
|
|
21
|
-
return;
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
try {
|
|
25
|
-
await mongoose.connect(uri);
|
|
26
|
-
this.isConnected = true;
|
|
27
|
-
loggers.agent.info("MongoDB connected successfully");
|
|
28
|
-
} catch (error) {
|
|
29
|
-
loggers.agent.error("Failed to connect to MongoDB:", error);
|
|
30
|
-
throw error;
|
|
31
|
-
}
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
public async disconnect(): Promise<void> {
|
|
35
|
-
if (!this.isConnected) {
|
|
36
|
-
return;
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
try {
|
|
40
|
-
await mongoose.disconnect();
|
|
41
|
-
this.isConnected = false;
|
|
42
|
-
loggers.agent.info("MongoDB disconnected successfully");
|
|
43
|
-
} catch (error) {
|
|
44
|
-
loggers.agent.error("Failed to disconnect from MongoDB:", error);
|
|
45
|
-
throw error;
|
|
46
|
-
}
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
public async getSessionHistory(sessionId: string): Promise<SessionObject> {
|
|
50
|
-
const chats = await ChatModel.find({ sessionId }).sort({
|
|
51
|
-
timestamp: 1,
|
|
52
|
-
});
|
|
53
|
-
|
|
54
|
-
loggers.agent.info(`Found ${chats.length} chats for session ${sessionId}`);
|
|
55
|
-
|
|
56
|
-
const sessionObject: SessionObject = { chats: {} };
|
|
57
|
-
chats.forEach((chat: ChatDocument) => {
|
|
58
|
-
const chatId = chat._id?.toString() || chat.id;
|
|
59
|
-
sessionObject.chats[chatId] = {
|
|
60
|
-
role: chat.role as ChatRole,
|
|
61
|
-
content: chat.content,
|
|
62
|
-
timestamp: chat.timestamp,
|
|
63
|
-
metadata: chat.metadata,
|
|
64
|
-
};
|
|
65
|
-
});
|
|
66
|
-
|
|
67
|
-
return sessionObject;
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
public async updateSessionHistory(
|
|
71
|
-
sessionId: string,
|
|
72
|
-
chat: ChatObject,
|
|
73
|
-
): Promise<void> {
|
|
74
|
-
loggers.agent.info(`Updating session history for session ${sessionId}`);
|
|
75
|
-
loggers.agent.info(`Chat: ${JSON.stringify(chat)}`);
|
|
76
|
-
|
|
77
|
-
await ChatModel.create({
|
|
78
|
-
sessionId,
|
|
79
|
-
role: chat.role,
|
|
80
|
-
content: chat.content,
|
|
81
|
-
timestamp: chat.timestamp,
|
|
82
|
-
metadata: chat.metadata,
|
|
83
|
-
});
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
public async storeQueryAndIntent(
|
|
87
|
-
query: string,
|
|
88
|
-
intent: string,
|
|
89
|
-
sessionId: string,
|
|
90
|
-
): Promise<void> {
|
|
91
|
-
// Intent 정보를 metadata에 저장
|
|
92
|
-
const chat: ChatObject = {
|
|
93
|
-
role: ChatRole.USER,
|
|
94
|
-
content: {
|
|
95
|
-
type: "text",
|
|
96
|
-
parts: [query],
|
|
97
|
-
},
|
|
98
|
-
timestamp: Date.now(),
|
|
99
|
-
metadata: {
|
|
100
|
-
intent,
|
|
101
|
-
query,
|
|
102
|
-
},
|
|
103
|
-
};
|
|
104
|
-
|
|
105
|
-
await this.updateSessionHistory(sessionId, chat);
|
|
106
|
-
}
|
|
107
|
-
}
|
|
1
|
+
export { MongoDBSession } from "./implements/session.memory";
|
|
2
|
+
export { MongoDBIntent } from "./implements/intent.memory";
|
package/models/chats.model.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import
|
|
1
|
+
import { type Document, Schema } from "mongoose";
|
|
2
2
|
|
|
3
3
|
// ChatRole enum
|
|
4
4
|
export enum ChatRole {
|
|
@@ -7,8 +7,43 @@ export enum ChatRole {
|
|
|
7
7
|
MODEL = "MODEL",
|
|
8
8
|
}
|
|
9
9
|
|
|
10
|
+
export const SessionObjectSchema = new Schema(
|
|
11
|
+
{
|
|
12
|
+
sessionId: {
|
|
13
|
+
type: String,
|
|
14
|
+
required: true,
|
|
15
|
+
index: true,
|
|
16
|
+
},
|
|
17
|
+
userId: {
|
|
18
|
+
type: String,
|
|
19
|
+
required: true,
|
|
20
|
+
index: true,
|
|
21
|
+
},
|
|
22
|
+
title: {
|
|
23
|
+
type: String,
|
|
24
|
+
required: false,
|
|
25
|
+
},
|
|
26
|
+
created_at: {
|
|
27
|
+
type: Number,
|
|
28
|
+
required: true,
|
|
29
|
+
},
|
|
30
|
+
updated_at: {
|
|
31
|
+
type: Number,
|
|
32
|
+
required: true,
|
|
33
|
+
}
|
|
34
|
+
},
|
|
35
|
+
);
|
|
36
|
+
|
|
37
|
+
export interface SessionDocument extends Document {
|
|
38
|
+
sessionId: string;
|
|
39
|
+
userId: string;
|
|
40
|
+
title?: string;
|
|
41
|
+
created_at: number;
|
|
42
|
+
updated_at: number;
|
|
43
|
+
}
|
|
44
|
+
|
|
10
45
|
// ChatContentObject schema
|
|
11
|
-
const ChatContentObjectSchema = new Schema(
|
|
46
|
+
export const ChatContentObjectSchema = new Schema(
|
|
12
47
|
{
|
|
13
48
|
type: { type: String, required: true },
|
|
14
49
|
parts: { type: [Schema.Types.Mixed], required: true },
|
|
@@ -17,7 +52,7 @@ const ChatContentObjectSchema = new Schema(
|
|
|
17
52
|
);
|
|
18
53
|
|
|
19
54
|
// ChatObject schema - 개별 문서로 저장
|
|
20
|
-
const ChatObjectSchema = new Schema(
|
|
55
|
+
export const ChatObjectSchema = new Schema(
|
|
21
56
|
{
|
|
22
57
|
sessionId: {
|
|
23
58
|
type: String,
|
|
@@ -42,9 +77,6 @@ const ChatObjectSchema = new Schema(
|
|
|
42
77
|
default: {},
|
|
43
78
|
},
|
|
44
79
|
},
|
|
45
|
-
{
|
|
46
|
-
timestamps: true,
|
|
47
|
-
},
|
|
48
80
|
);
|
|
49
81
|
|
|
50
82
|
// Chat Document interface
|
|
@@ -60,6 +92,3 @@ export interface ChatDocument extends Document {
|
|
|
60
92
|
createdAt: Date;
|
|
61
93
|
updatedAt: Date;
|
|
62
94
|
}
|
|
63
|
-
|
|
64
|
-
// Export the model
|
|
65
|
-
export const ChatModel = mongoose.model<ChatDocument>("Chat", ChatObjectSchema);
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import mongoose, { type Document, Schema } from "mongoose";
|
|
2
|
+
|
|
3
|
+
const IntentObjectSchema = new Schema(
|
|
4
|
+
{
|
|
5
|
+
name: {
|
|
6
|
+
type: String,
|
|
7
|
+
required: true,
|
|
8
|
+
index: true,
|
|
9
|
+
},
|
|
10
|
+
description: {
|
|
11
|
+
type: String,
|
|
12
|
+
required: true,
|
|
13
|
+
},
|
|
14
|
+
prompt: {
|
|
15
|
+
type: String,
|
|
16
|
+
required: false,
|
|
17
|
+
},
|
|
18
|
+
llm: {
|
|
19
|
+
type: String,
|
|
20
|
+
required: false,
|
|
21
|
+
},
|
|
22
|
+
}
|
|
23
|
+
);
|
|
24
|
+
|
|
25
|
+
export interface IntentDocument extends Document {
|
|
26
|
+
name: string;
|
|
27
|
+
description: string;
|
|
28
|
+
prompt?: string;
|
|
29
|
+
llm?: string;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
export const IntentModel = mongoose.model<IntentDocument>("Intent", IntentObjectSchema);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ainetwork/adk-provider-memory-mongodb",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.2",
|
|
4
4
|
"author": "AI Network (https://ainetwork.ai)",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"engines": {
|
|
@@ -26,7 +26,7 @@
|
|
|
26
26
|
"clean": "rm -rf dist"
|
|
27
27
|
},
|
|
28
28
|
"dependencies": {
|
|
29
|
-
"@ainetwork/adk": "^0.1.
|
|
29
|
+
"@ainetwork/adk": "^0.1.7",
|
|
30
30
|
"mongoose": "^8.16.5"
|
|
31
31
|
},
|
|
32
32
|
"devDependencies": {
|
|
@@ -36,5 +36,5 @@
|
|
|
36
36
|
"publishConfig": {
|
|
37
37
|
"access": "public"
|
|
38
38
|
},
|
|
39
|
-
"gitHead": "
|
|
39
|
+
"gitHead": "4098aacea7a18099aa020ef5d331cdce0d59c3f3"
|
|
40
40
|
}
|
|
@@ -1,50 +0,0 @@
|
|
|
1
|
-
import mongoose, { type Document, Schema } from "mongoose";
|
|
2
|
-
|
|
3
|
-
const MessageSchema = new Schema(
|
|
4
|
-
{
|
|
5
|
-
role: {
|
|
6
|
-
type: String,
|
|
7
|
-
enum: ["system", "user", "assistant", "tool", "function"],
|
|
8
|
-
required: true,
|
|
9
|
-
},
|
|
10
|
-
content: {
|
|
11
|
-
type: Schema.Types.Mixed, // string 또는 object array
|
|
12
|
-
required: true,
|
|
13
|
-
},
|
|
14
|
-
},
|
|
15
|
-
{ _id: false },
|
|
16
|
-
);
|
|
17
|
-
|
|
18
|
-
export interface IntentTriggeringInfoDocument extends Document {
|
|
19
|
-
context: {
|
|
20
|
-
messages: Array<{
|
|
21
|
-
role: string;
|
|
22
|
-
content:
|
|
23
|
-
| string
|
|
24
|
-
| Array<
|
|
25
|
-
| { type: "text"; text: string }
|
|
26
|
-
| { type: "image_url"; image_url: { url: string } }
|
|
27
|
-
>;
|
|
28
|
-
}>;
|
|
29
|
-
};
|
|
30
|
-
intent: {
|
|
31
|
-
name: string;
|
|
32
|
-
description: string;
|
|
33
|
-
};
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
const IntentTriggeringInfoSchema = new Schema<IntentTriggeringInfoDocument>({
|
|
37
|
-
context: {
|
|
38
|
-
messages: [MessageSchema],
|
|
39
|
-
},
|
|
40
|
-
intent: {
|
|
41
|
-
name: { type: String, required: true },
|
|
42
|
-
description: { type: String, required: true },
|
|
43
|
-
},
|
|
44
|
-
});
|
|
45
|
-
|
|
46
|
-
export const IntentTriggeringInfoModel =
|
|
47
|
-
mongoose.model<IntentTriggeringInfoDocument>(
|
|
48
|
-
"IntentTriggeringInfo",
|
|
49
|
-
IntentTriggeringInfoSchema,
|
|
50
|
-
);
|