-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Signed-off-by: sarthakjdev <[email protected]>
- Loading branch information
1 parent
77eb80c
commit 13d3b54
Showing
7 changed files
with
142 additions
and
87 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
export enum AiConversationRoleEnum { | ||
User = 'user', | ||
Ai = 'assistant' | ||
} | ||
|
||
export type ConversationMessageType = { | ||
role: AiConversationRoleEnum | ||
content: string | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,11 +1,28 @@ | ||
import NodeCache from 'node-cache' | ||
import { AiConversationRoleEnum, ConversationMessageType } from '~/types' | ||
Check failure on line 1 in apps/wapi-ai-chatbot/src/utils/cache.ts GitHub Actions / build-and-lint
|
||
import { caching } from 'cache-manager' | ||
|
||
const cache = new NodeCache() | ||
const cacheStore = caching({ | ||
store: 'memory' | ||
}) | ||
|
||
export const setCache = (key: string, value: any, ttl: number = 3600) => { | ||
cache.set(key, value, ttl) | ||
export async function cacheData(params: { key: string; data: any; ttl?: number }) { | ||
const { key, ttl, data } = params | ||
await cacheStore.set(key, data, { ...(ttl ? { ttl: ttl } : {}) }) | ||
} | ||
|
||
export const getCache = (key: string) => { | ||
return cache.get(key) | ||
export async function getCachedData<T>(key: string): Promise<T> { | ||
const response = await cacheStore.get(key) | ||
console.log(response) | ||
return response as T | ||
} | ||
|
||
export function computeCacheKey(params: { id: string; context: string }) { | ||
return `${params.id}-${params.context}` | ||
} | ||
|
||
export function getConversationContextCacheKey(phoneNumber: string) { | ||
return computeCacheKey({ | ||
id: phoneNumber, | ||
context: 'conversation' | ||
}) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,34 +1,81 @@ | ||
import { OpenAI } from 'openai' | ||
import { cacheData, computeCacheKey, getCachedData, getConversationContextCacheKey } from './cache' | ||
import { AiConversationRoleEnum, ConversationMessageType } from '~/types' | ||
|
||
const openAiApiKey = process.env.OPEN_AI_API_KEY | ||
const organizationId = process.env.OPEN_AI_ORG_ID | ||
const projectId = process.env.OPEN_AI_PROJECT_ID | ||
|
||
if (!openAiApiKey) { | ||
if (!openAiApiKey || !organizationId || !projectId) { | ||
throw new Error('OPEN_AI_API_KEY not defined!') | ||
} | ||
|
||
const OpenApiClient = new OpenAI({ | ||
apiKey: openAiApiKey, | ||
project: 'proj_viwVq5nzCR5Mj4TnIw4FQoNO', | ||
organization: 'org-wwfaGhYXIA7CBUSg6x8DbKYj' | ||
project: projectId, | ||
organization: organizationId | ||
}) | ||
|
||
export async function askAi(message: string): Promise<string | null> { | ||
|
||
export async function askAi(message: string, fromPhoneNumber: string): Promise<string> { | ||
try { | ||
const chatCompletion = await OpenApiClient.chat.completions.create({ | ||
messages: [{ role: 'user', content: message }], | ||
model: 'gpt-3.5-turbo' | ||
const contextCacheKey = getConversationContextCacheKey(fromPhoneNumber) | ||
const context = await getCachedData<ConversationMessageType[]>(contextCacheKey) | ||
|
||
let response = 'Sorry, I am not able to understand that.' | ||
const responseCacheKey = computeCacheKey({ | ||
context: 'response_cache', | ||
id: message.trim() | ||
}) | ||
const cachedResponse = await getCachedData<string>(responseCacheKey) | ||
if (cachedResponse) { | ||
response = cachedResponse | ||
} else { | ||
const chatCompletion = await OpenApiClient.chat.completions.create({ | ||
messages: [ | ||
{ | ||
role: 'system', | ||
content: `You are an intelligent assistant helping a user with their queries. You can provide information, answer questions, and help the user complete tasks. | ||
You are a developer relation engineer for a product named as Wapi.js. | ||
Wapi.js is an SDK to build chat bots and to integrate WhatsApp API with your application very easily. | ||
The SDK is authored by Sarthak Jain having github at https://github.com/sarthakjdev and is an open-source SDk which is free to use. | ||
Users can use the SDK to build chatbots for customer support, marketing, notifications, and more! Leverage WhatsApp Business API. | ||
You are required to give very to the point and very clear answers to the user queries. | ||
Also, you can reveal your identity, ack like a human, and provide information about the product. | ||
Never ever accept that you are an AI or a chatbot or an intelligent assistant. | ||
` | ||
}, | ||
...(context ? context : []), | ||
{ | ||
role: 'user', | ||
content: message | ||
} | ||
], | ||
model: 'gpt-4' | ||
}) | ||
console.log(JSON.stringify({ chatCompletion })) | ||
const aiResponse = chatCompletion.choices[0].message.content | ||
if (aiResponse) response = aiResponse | ||
} | ||
|
||
console.log(JSON.stringify({ chatCompletion })) | ||
await cacheData({ | ||
key: contextCacheKey, | ||
data: [ | ||
...(context ? context : []), | ||
{ | ||
role: AiConversationRoleEnum.User, | ||
content: message | ||
}, | ||
{ | ||
role: AiConversationRoleEnum.Ai, | ||
content: response | ||
}, | ||
|
||
return chatCompletion.choices[0].message.content | ||
] | ||
}) | ||
return response | ||
} catch (error) { | ||
console.log({ error }) | ||
return null | ||
return 'Sorry, I am not able to understand that.' | ||
} | ||
} | ||
|
||
|
||
export async function generateTranscription(){ | ||
|
||
} |
Oops, something went wrong.