Skip to content

Commit c3caaf5

Browse files
authored
Merge pull request #1002 from ayushjain6013/fetaure/upstash_redis
Added Upstash Redis Memory support
2 parents 7d6cb18 + 8b555e0 commit c3caaf5

File tree

4 files changed

+157
-0
lines changed

4 files changed

+157
-0
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
import { INodeParams, INodeCredential } from '../src/Interface'
2+
3+
class UpstashRedisMemoryApi implements INodeCredential {
4+
label: string
5+
name: string
6+
version: number
7+
description: string
8+
inputs: INodeParams[]
9+
10+
constructor() {
11+
this.label = 'Upstash Redis Memory API'
12+
this.name = 'upstashRedisMemoryApi'
13+
this.version = 1.0
14+
this.description =
15+
'Refer to <a target="_blank" href="https://upstash.com/docs/redis/overall/getstarted">official guide</a> on how to create redis instance and get redis REST Token'
16+
this.inputs = [
17+
{
18+
label: 'Upstash Redis REST Token',
19+
name: 'upstashRestToken',
20+
type: 'password'
21+
}
22+
]
23+
}
24+
}
25+
26+
module.exports = { credClass: UpstashRedisMemoryApi }
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,118 @@
1+
import { INode, INodeData, INodeParams } from '../../../src/Interface'
2+
import { getBaseClasses, getCredentialData, getCredentialParam } from '../../../src/utils'
3+
import { ICommonObject } from '../../../src'
4+
import { BufferMemory, BufferMemoryInput } from 'langchain/memory'
5+
import { UpstashRedisChatMessageHistory } from 'langchain/stores/message/upstash_redis'
6+
7+
class UpstashRedisBackedChatMemory_Memory implements INode {
8+
label: string
9+
name: string
10+
version: number
11+
description: string
12+
type: string
13+
icon: string
14+
category: string
15+
baseClasses: string[]
16+
credential: INodeParams
17+
inputs: INodeParams[]
18+
19+
constructor() {
20+
this.label = 'Upstash Redis-Backed Chat Memory'
21+
this.name = 'upstashRedisBackedChatMemory'
22+
this.version = 1.0
23+
this.type = 'UpstashRedisBackedChatMemory'
24+
this.icon = 'upstash.svg'
25+
this.category = 'Memory'
26+
this.description = 'Summarizes the conversation and stores the memory in Upstash Redis server'
27+
this.baseClasses = [this.type, ...getBaseClasses(BufferMemory)]
28+
this.credential = {
29+
label: 'Connect Credential',
30+
name: 'credential',
31+
type: 'credential',
32+
description: 'Configure password authentication on your upstash redis instance',
33+
credentialNames: ['upstashRedisMemoryApi']
34+
}
35+
this.inputs = [
36+
{
37+
label: 'Upstash Redis REST URL',
38+
name: 'baseURL',
39+
type: 'string',
40+
placeholder: 'https://<your-url>.upstash.io'
41+
},
42+
{
43+
label: 'Session Id',
44+
name: 'sessionId',
45+
type: 'string',
46+
description: 'If not specified, the first CHAT_MESSAGE_ID will be used as sessionId',
47+
default: '',
48+
additionalParams: true,
49+
optional: true
50+
},
51+
{
52+
label: 'Session Timeouts',
53+
name: 'sessionTTL',
54+
type: 'number',
55+
description: 'Omit this parameter to make sessions never expire',
56+
additionalParams: true,
57+
optional: true
58+
}
59+
]
60+
}
61+
62+
async init(nodeData: INodeData, _: string, options: ICommonObject): Promise<any> {
63+
return initalizeUpstashRedis(nodeData, options)
64+
}
65+
66+
async clearSessionMemory(nodeData: INodeData, options: ICommonObject): Promise<void> {
67+
const redis = await initalizeUpstashRedis(nodeData, options)
68+
const sessionId = nodeData.inputs?.sessionId as string
69+
const chatId = options?.chatId as string
70+
options.logger.info(`Clearing Upstash Redis memory session ${sessionId ? sessionId : chatId}`)
71+
await redis.clear()
72+
options.logger.info(`Successfully cleared Upstash Redis memory session ${sessionId ? sessionId : chatId}`)
73+
}
74+
}
75+
76+
const initalizeUpstashRedis = async (nodeData: INodeData, options: ICommonObject): Promise<BufferMemory> => {
77+
const baseURL = nodeData.inputs?.baseURL as string
78+
const sessionId = nodeData.inputs?.sessionId as string
79+
const sessionTTL = nodeData.inputs?.sessionTTL as string
80+
const chatId = options?.chatId as string
81+
82+
let isSessionIdUsingChatMessageId = false
83+
if (!sessionId && chatId) isSessionIdUsingChatMessageId = true
84+
85+
const credentialData = await getCredentialData(nodeData.credential ?? '', options)
86+
const upstashRestToken = getCredentialParam('upstashRestToken', credentialData, nodeData)
87+
88+
const redisChatMessageHistory = new UpstashRedisChatMessageHistory({
89+
sessionId: sessionId ? sessionId : chatId,
90+
sessionTTL: sessionTTL ? parseInt(sessionTTL, 10) : undefined,
91+
config: {
92+
url: baseURL,
93+
token: upstashRestToken
94+
}
95+
})
96+
97+
const memory = new BufferMemoryExtended({
98+
chatHistory: redisChatMessageHistory,
99+
isSessionIdUsingChatMessageId
100+
})
101+
102+
return memory
103+
}
104+
105+
interface BufferMemoryExtendedInput {
106+
isSessionIdUsingChatMessageId: boolean
107+
}
108+
109+
class BufferMemoryExtended extends BufferMemory {
110+
isSessionIdUsingChatMessageId? = false
111+
112+
constructor(fields: BufferMemoryInput & Partial<BufferMemoryExtendedInput>) {
113+
super(fields)
114+
this.isSessionIdUsingChatMessageId = fields.isSessionIdUsingChatMessageId
115+
}
116+
}
117+
118+
module.exports = { nodeClass: UpstashRedisBackedChatMemory_Memory }
Loading

packages/components/package.json

+1
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
"@supabase/supabase-js": "^2.29.0",
2929
"@types/js-yaml": "^4.0.5",
3030
"@types/jsdom": "^21.1.1",
31+
"@upstash/redis": "^1.22.1",
3132
"@zilliz/milvus2-sdk-node": "^2.2.24",
3233
"apify-client": "^2.7.1",
3334
"axios": "^0.27.2",

0 commit comments

Comments
 (0)