11import { AIMessage , BaseMessage , HumanMessage } from "@langchain/core/messages" ;
2- import { PromptTemplate } from "@langchain/core/prompts" ;
3- import { RunnableSequence } from "@langchain/core/runnables" ;
2+ import type { ChatPromptTemplate } from "@langchain/core/prompts" ;
43import { ChatOpenAI } from "@langchain/openai" ;
5- import { AgentExecutor , AgentStep } from "langchain/agents" ;
6- import { formatLogToString } from "langchain/agents/format_scratchpad/log" ;
7- import { ReActSingleInputOutputParser } from "langchain/agents/react/output_parser" ;
4+ import { AgentExecutor , createStructuredChatAgent } from "langchain/agents" ;
5+ import { pull } from "langchain/hub" ;
86import {
97 BufferWindowMemory ,
108 ChatMessageHistory ,
119 ConversationSummaryMemory ,
1210} from "langchain/memory" ;
13- import { renderTextDescription } from "langchain/tools/render" ;
1411import {
12+ MODEL_TEMPERATURE ,
1513 OPENROUTER_API_KEY ,
1614 OPENROUTER_MEMORY_TYPE ,
1715 OPENROUTER_MSG_MEMORY_LIMIT ,
18- OPEN_ROUTER_SYSTEM_MESSAGE ,
1916 SUMMARY_LLM_MODEL ,
2017} from "../constants" ;
2118import {
2219 getLLMModel ,
2320 getOpenRouterConversationFor ,
2421 getOpenRouterMemoryFor ,
2522} from "../crud/conversation" ;
26- import { toolNames , tools } from "./tools-openrouter" ;
23+ import { tools } from "./tools-openrouter" ;
2724
28- const OPENROUTER_BASE_URL = "https://openrouter.ai" ;
25+ function parseMessageHistory (
26+ rawHistory : { [ key : string ] : string } [ ]
27+ ) : ( HumanMessage | AIMessage ) [ ] {
28+ return rawHistory . map ( ( messageObj ) => {
29+ const messageType = Object . keys ( messageObj ) [ 0 ] ;
30+ const messageContent = messageObj [ messageType ] ;
2931
30- function parseMessageHistory ( rawHistory : string ) : ( HumanMessage | AIMessage ) [ ] {
31- const lines = rawHistory . split ( "\n" ) ;
32- return lines
33- . map ( ( line ) => {
34- if ( line . startsWith ( "Human: " ) ) {
35- return new HumanMessage ( line . replace ( "Human: " , "" ) ) ;
36- } else {
37- return new AIMessage ( line . replace ( "AI: " , "" ) ) ;
38- }
39- } )
40- . filter (
41- ( message ) : message is HumanMessage | AIMessage => message !== undefined
42- ) ;
32+ if ( messageType === "HumanMessage" ) {
33+ return new HumanMessage ( messageContent ) ;
34+ } else {
35+ return new AIMessage ( messageContent ) ;
36+ }
37+ } ) ;
4338}
4439
4540async function createMemoryForOpenRouter ( chat : string ) {
@@ -54,21 +49,23 @@ async function createMemoryForOpenRouter(chat: string) {
5449 openAIApiKey : OPENROUTER_API_KEY ,
5550 } ,
5651 {
57- basePath : ` ${ OPENROUTER_BASE_URL } / api/v1` ,
52+ basePath : "https://openrouter.ai/ api/v1" ,
5853 }
5954 ) ;
6055
6156 memory = new ConversationSummaryMemory ( {
6257 memoryKey : "chat_history" ,
6358 inputKey : "input" ,
64- outputKey : 'output' ,
59+ outputKey : "output" ,
60+ returnMessages : true ,
6561 llm : summaryLLM ,
6662 } ) ;
6763 } else {
6864 memory = new BufferWindowMemory ( {
6965 memoryKey : "chat_history" ,
7066 inputKey : "input" ,
71- outputKey : 'output' ,
67+ outputKey : "output" ,
68+ returnMessages : true ,
7269 k : OPENROUTER_MSG_MEMORY_LIMIT ,
7370 } ) ;
7471 }
@@ -82,9 +79,12 @@ async function createMemoryForOpenRouter(chat: string) {
8279 let memoryString = await getOpenRouterMemoryFor ( chat ) ;
8380 if ( memoryString === undefined ) return ;
8481
85- const pastMessages = parseMessageHistory ( memoryString ) ;
82+ const pastMessages = parseMessageHistory ( JSON . parse ( memoryString ) ) ;
8683 memory . chatHistory = new ChatMessageHistory ( pastMessages ) ;
8784 }
85+ } else {
86+ let memoryString : BaseMessage [ ] = [ ] ;
87+ memory . chatHistory = new ChatMessageHistory ( memoryString ) ;
8888 }
8989
9090 return memory ;
@@ -99,57 +99,30 @@ export async function createExecutorForOpenRouter(
9999 {
100100 modelName : llmModel ,
101101 streaming : true ,
102- temperature : 0.7 ,
102+ temperature : MODEL_TEMPERATURE ,
103103 openAIApiKey : OPENROUTER_API_KEY ,
104104 } ,
105105 {
106- basePath : ` ${ OPENROUTER_BASE_URL } / api/v1` ,
106+ basePath : "https://openrouter.ai/ api/v1" ,
107107 }
108108 ) ;
109109
110- const modelWithStop = openRouterChat . bind ( {
111- stop : [ "\nObservation" ] ,
112- } ) ;
113- const memory = await createMemoryForOpenRouter ( chat ) ;
110+ const prompt = await pull < ChatPromptTemplate > ( "luisotee/wa-assistant" ) ;
114111
115- const systemMessageOpenRouter = PromptTemplate . fromTemplate ( `
116- ${ OPEN_ROUTER_SYSTEM_MESSAGE }
117-
118- ${ context } `) ;
112+ const memory = await createMemoryForOpenRouter ( chat ) ;
119113
120- const promptWithInputs = await systemMessageOpenRouter . partial ( {
121- tools : renderTextDescription ( tools ) ,
122- tool_names : toolNames . join ( "," ) ,
114+ const agent = await createStructuredChatAgent ( {
115+ llm : openRouterChat ,
116+ tools,
117+ prompt,
123118 } ) ;
124119
125- const agent = RunnableSequence . from ( [
126- {
127- input : ( i : {
128- input : string ;
129- steps : AgentStep [ ] ;
130- chat_history : BaseMessage [ ] ;
131- } ) => i . input ,
132- agent_scratchpad : ( i : {
133- input : string ;
134- steps : AgentStep [ ] ;
135- chat_history : BaseMessage [ ] ;
136- } ) => formatLogToString ( i . steps ) ,
137- chat_history : ( i : {
138- input : string ;
139- steps : AgentStep [ ] ;
140- chat_history : BaseMessage [ ] ;
141- } ) => i . chat_history ,
142- } ,
143- promptWithInputs ,
144- modelWithStop ,
145- new ReActSingleInputOutputParser ( { toolNames } ) ,
146- ] ) ;
147-
148120 const executor = AgentExecutor . fromAgentAndTools ( {
149121 agent,
150122 tools,
151123 memory,
124+ //verbose: true,
152125 } ) ;
153126
154127 return executor ;
155- }
128+ }
0 commit comments