-
Notifications
You must be signed in to change notification settings - Fork 122
/
index.ts
118 lines (95 loc) · 2.91 KB
/
index.ts
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
// @ts-ignore
import * as fs from 'fs'
import 'dotenv/config'
import { Sandbox, Execution } from '@e2b/code-interpreter'
import Anthropic from '@anthropic-ai/sdk'
import { Buffer } from 'buffer'
import { MODEL_NAME, SYSTEM_PROMPT, tools } from './model'
import { codeInterpret } from './codeInterpreter'
import { scrapeAirbnb } from './scraping'
const anthropic = new Anthropic()
async function chat(
codeInterpreter: Sandbox,
userMessage: string
): Promise<Execution | undefined> {
console.log('Waiting for Claude...')
const msg = await anthropic.messages.create({
model: MODEL_NAME,
system: SYSTEM_PROMPT,
max_tokens: 4096,
messages: [{ role: 'user', content: userMessage }],
tools,
})
console.log(
`\n${'='.repeat(50)}\nModel response: ${msg.content}\n${'='.repeat(50)}`
)
console.log(msg)
if (msg.stop_reason === 'tool_use') {
const toolBlock = msg.content.find((block) => block.type === 'tool_use')
// @ts-ignore
const toolName = toolBlock?.name ?? ''
// @ts-ignore
const toolInput = toolBlock?.input ?? ''
console.log(
`\n${'='.repeat(50)}\nUsing tool: ${toolName}\n${'='.repeat(50)}`
)
if (toolName === 'execute_python') {
const code = toolInput.code
return codeInterpret(codeInterpreter, code)
}
return undefined
}
}
async function run() {
// Load the Airbnb prices data from the JSON file
let data
const readDataFromFile = () => {
try {
return fs.readFileSync('airbnb_listings.json', 'utf8')
} catch (err) {
if (err.code === 'ENOENT') {
console.log('File not found, scraping data...')
return null
} else {
throw err
}
}
}
const fetchData = async () => {
data = readDataFromFile()
if (!data || data.trim() === '[]') {
console.log('File is empty or contains an empty list, scraping data...')
data = await scrapeAirbnb()
}
}
await fetchData()
// Parse the JSON data
const prices = JSON.parse(data)
// Convert prices array to a string representation of a Python list
const pricesList = JSON.stringify(prices)
const userMessage = `
Load the Airbnb prices data from the airbnb listing below and visualize the distribution of prices with a histogram. Listing data: ${pricesList}
`
const codeInterpreter = await Sandbox.create()
const codeOutput = await chat(codeInterpreter, userMessage)
if (!codeOutput) {
console.log('No code output')
return
}
const logs = codeOutput.logs
console.log(logs)
if (codeOutput.results.length == 0) {
console.log('No results')
return
}
const firstResult = codeOutput.results[0]
console.log(firstResult.text)
if (firstResult.png) {
const pngData = Buffer.from(firstResult.png, 'base64')
const filename = 'airbnb_prices_chart.png'
fs.writeFileSync(filename, pngData)
console.log(`✅ Saved chart to ${filename}`)
}
await codeInterpreter.kill()
}
run()