-
Notifications
You must be signed in to change notification settings - Fork 30
/
chat_anthropic.ts
134 lines (117 loc) · 3.77 KB
/
chat_anthropic.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
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
import {Contract, ethers, TransactionReceipt, Wallet} from "ethers";
import ABI from "./abis/AnthropicChatGpt.json";
import * as readline from 'readline';
require("dotenv").config()
interface Message {
role: string,
content: string,
}
async function main() {
const rpcUrl = process.env.RPC_URL
if (!rpcUrl) throw Error("Missing RPC_URL in .env")
const privateKey = process.env.PRIVATE_KEY
if (!privateKey) throw Error("Missing PRIVATE_KEY in .env")
const contractAddress = process.env.ANTROPIC_CONTRACT_ADDRESS
if (!contractAddress) throw Error("Missing ANTROPIC_CONTRACT_ADDRESS in .env")
const provider = new ethers.JsonRpcProvider(rpcUrl)
const wallet = new Wallet(
privateKey, provider
)
const contract = new Contract(contractAddress, ABI, wallet)
const message = await getUserInput()
// Call the startChat function
const transactionResponse = await contract.startChat(message)
const receipt = await transactionResponse.wait()
console.log(`Message sent, tx hash: ${receipt.hash}`)
console.log(`Chat started with message: "${message}"`)
// Get the chat ID from transaction receipt logs
let chatId = getChatId(receipt, contract);
console.log(`Created chat ID: ${chatId}`)
if (!chatId && chatId !== 0) {
return
}
let allMessages: Message[] = []
// Run the chat loop: read messages and send messages
while (true) {
const newMessages: Message[] = await getNewMessages(contract, chatId, allMessages.length);
if (newMessages) {
for (let message of newMessages) {
console.log(`${message.role}: ${message.content}`)
allMessages.push(message)
if (allMessages.at(-1)?.role == "assistant") {
try {
const toolRunning: string = await contract.toolRunning(chatId)
console.log(`Tool running: ${toolRunning}`)
if (toolRunning !== "") {
continue
}
} catch (error) {
}
const message = getUserInput()
const transactionResponse = await contract.addMessage(message, chatId)
const receipt = await transactionResponse.wait()
console.log(`Message sent, tx hash: ${receipt.hash}`)
}
}
}
await new Promise(resolve => setTimeout(resolve, 2000))
}
}
async function getUserInput(): Promise<string | undefined> {
const rl = readline.createInterface({
input: process.stdin,
output: process.stdout
})
const question = (query: string): Promise<string> => {
return new Promise((resolve) => {
rl.question(query, (answer) => {
resolve(answer)
})
})
}
try {
const input = await question("Message ChatGPT: ")
rl.close()
return input
} catch (err) {
console.error('Error getting user input:', err)
rl.close()
}
}
function getChatId(receipt: TransactionReceipt, contract: Contract) {
let chatId
for (const log of receipt.logs) {
try {
const parsedLog = contract.interface.parseLog(log)
if (parsedLog && parsedLog.name === "ChatCreated") {
// Second event argument
chatId = ethers.toNumber(parsedLog.args[1])
}
} catch (error) {
// This log might not have been from your contract, or it might be an anonymous log
console.log("Could not parse log:", log)
}
}
return chatId;
}
async function getNewMessages(
contract: Contract,
chatId: number,
currentMessagesCount: number
): Promise<Message[]> {
const messages = await contract.getMessageHistory(chatId)
const newMessages: Message[] = []
messages.forEach((message: any, i: number) => {
if (i >= currentMessagesCount) {
newMessages.push(
{
role: message.role,
content: message.content[0].value,
}
);
}
})
return newMessages;
}
main()
.then(() => console.log("Done"))