hackoon
Version:
Immunefi Hackoon CLI
55 lines (54 loc) • 3.67 kB
JavaScript
import React, { useMemo, useRef } from "react";
import { useChat } from "ai/react";
import { Box, Text } from "ink";
import TextInput from "ink-text-input";
import Spinner from "ink-spinner";
import Gradient from "ink-gradient";
import env from "./lib/env.js";
import { getErrorMessage } from "./lib/getErrorMessage.js";
import { getUrlOnly, isValidUrl } from "./lib/url.js";
import { getContextDocuments, getContextSources } from "./lib/context.js";
import { getRemainingMessagesPerHour } from "./lib/ratelimit.js";
const NUMBER_OF_MESSAGES_TO_RENDER = -4;
export default function App({ apiKey }) {
const { messages, handleInputChange, handleSubmit, input, isLoading, error, data } = useChat({
// set the API_URL to the value of the API_URL environment variable or use the default value or prod
// remember this is a cli app so no need to use an .env file
api: env.API_URL,
sendExtraMessageFields: true,
headers: {
Authorization: `Bearer ${apiKey}`,
},
});
const remainingMessages = useMemo(() => getRemainingMessagesPerHour(data), [data]);
const remainingMessagesText = remainingMessages ? ` (${remainingMessages}/h left) :` : ":";
return (React.createElement(Box, { marginLeft: 2, flexDirection: "column", marginTop: 1 },
React.createElement(Box, { marginTop: 1 },
React.createElement(Text, null,
"Hello I'm ",
React.createElement(Gradient, { name: "passion" }, "Hackoon"),
", how can I help you today?")),
React.createElement(Box, { marginY: 1, display: "flex", flexDirection: "column" }, error ? (React.createElement(Text, { color: "red" }, getErrorMessage(error))) : (messages.slice(NUMBER_OF_MESSAGES_TO_RENDER).map((message, index) => (React.createElement(Box, { key: index, marginTop: 1 }, message.role === "user" ? (React.createElement(Gradient, { name: "passion" }, message.content)) : (React.createElement(SystemMessage, { text: message.content, data: data }))))))),
isLoading ? (React.createElement(Text, { color: "green" },
React.createElement(Spinner, { type: "dots" }))) : null,
React.createElement(Box, { marginTop: 1 },
React.createElement(Box, { marginRight: 2 },
React.createElement(Text, null, "Ask your question"),
remainingMessagesText ? React.createElement(Text, { bold: true }, remainingMessagesText) : null),
React.createElement(TextInput, { value: input, onChange: (value) => handleInputChange({ target: { value } }), onSubmit: (value) => handleSubmit({ target: { value }, preventDefault: () => { } }) }))));
}
function SystemMessage({ text, data }) {
const contextRef = useRef(getContextDocuments(data));
const context = contextRef.current;
return (React.createElement(Box, { flexDirection: "column" },
React.createElement(Text, null, text),
context.length > 0 && (React.createElement(Box, { flexDirection: "column", marginTop: 1 },
React.createElement(Text, { dimColor: true }, "Hackoon can make mistakes. Consider checking important information."),
React.createElement(Text, { dimColor: true }, "This version of Hackoon is scoped to FAQs about projects and Immunefi."),
React.createElement(Text, null, "---------------------------------"),
React.createElement(Text, { dimColor: true }, "Resources"),
getContextSources(context).map((url, idx) => isValidUrl(url) ? (React.createElement(Text, { key: idx, dimColor: true },
idx + 1,
". ",
getUrlOnly(url))) : null)))));
}