-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathsimple-agent.js
More file actions
131 lines (110 loc) · 3.93 KB
/
Copy pathsimple-agent.js
File metadata and controls
131 lines (110 loc) · 3.93 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
import { createReactAgent } from '@langchain/langgraph/prebuilt'
import { ChatOpenAI } from '@langchain/openai'
import { MemorySaver } from '@langchain/langgraph'
import { SerpAPI } from '@langchain/community/tools/serpapi'
import { createServer } from 'http'
import express from 'express'
import { WebSocketServer } from 'ws'
// Helper function to format JSON report into readable text
function formatReportFromJSON(report) {
let formatted = `# ${report.headline}\n\n`;
formatted += `${report.summary}\n\n`;
formatted += `## Key Points\n\n`;
for (const kp of report.key_points) {
formatted += `**${kp.point}**\n${kp.details}\n\n`;
}
formatted += `## Insights\n\n${report.insights}\n\n`;
formatted += `## Conclusion\n\n${report.conclusion}`;
return formatted;
}
const memory = new MemorySaver()
const getNews = new SerpAPI(process.env.SERP_KEY, {
hl: "en",
gl: "us"
})
const model = new ChatOpenAI({
model: 'gpt-4o'
})
const app = createReactAgent({
llm: model,
tools: [getNews],
checkpointer: memory,
systemMessage: `You are a helpful news analyst assistant. When a user asks for news about a topic:
1. Use the search tool to find current news articles relevant to 2025
2. After gathering information, respond in JSON format with the following structure:
{
"reasoning": {
"query_analysis": "Your analysis of what information was needed",
"sources_evaluated": "Summary of sources you found",
"synthesis_approach": "How you synthesized the information"
},
"report": {
"headline": "Compelling headline",
"summary": "Comprehensive summary",
"key_points": [
{"point": "Key point 1", "details": "Details about it"},
{"point": "Key point 2", "details": "Details about it"}
],
"insights": "Your analysis and insights",
"conclusion": "Concluding thoughts"
},
"metadata": {
"sources_count": 5,
"confidence": 0.9
}
}
3. Think through your reasoning step-by-step before providing the final report
4. Keep your response informative but conversational
You MUST respond in valid JSON format following the structure above.`
})
async function generateNews (topic, session_id) {
const config = {
configurable:{
thread_id: session_id
}
}
try {
const output = await app.invoke({ messages: [{ role: 'user', content: `Get news about: ${topic}` }] }, config)
console.log(output.messages)
// Parse and format the final JSON response
const finalMessage = output.messages.at(-1);
let formattedReport;
if (typeof finalMessage?.content === 'string') {
try {
const jsonResponse = JSON.parse(finalMessage.content);
if (jsonResponse.report) {
formattedReport = formatReportFromJSON(jsonResponse.report);
console.log('📄 Formatted report generated');
}
} catch (e) {
console.log('ℹ️ Response is not JSON formatted');
}
}
return { output, formattedReport }
} catch (err) {
console.log(err)
return { output: undefined, formattedReport: undefined }
}
}
// Backend
const ex = express()
ex.use(express.static('public')) // serves index.html
const server = createServer(ex)
const wss = new WebSocketServer({ server, path: '/ws' })
wss.on('connection', socket => {
socket.on('message', async raw => {
try {
const { command, topic, session_id } = JSON.parse(raw)
if (command === 'lookup news') {
const result = await generateNews(topic, session_id)
// Use formatted report if available, otherwise fall back to raw content
const news = result?.formattedReport || result?.output?.messages?.at(-1)?.content || 'No response available'
socket.send(JSON.stringify({ news }))
}
} catch (e) {
console.error(e)
socket.send(JSON.stringify({ news: 'Oops, something went wrong!' }))
}
})
})
server.listen(2999, () => console.log('http://localhost:2999'))