File size: 4,367 Bytes
8214506 82b1b1d 0970991 82b1b1d 1fe47b1 82b1b1d 1fe47b1 82b1b1d 8214506 0970991 8214506 82b1b1d 8214506 1fe47b1 82b1b1d 0970991 8214506 82b1b1d 0970991 82b1b1d 8214506 1fe47b1 8214506 82b1b1d 0970991 8214506 82b1b1d 0970991 1fe47b1 0970991 82b1b1d 8214506 82b1b1d 8214506 82b1b1d 8214506 82b1b1d 8214506 82b1b1d 8214506 82b1b1d 8214506 82b1b1d 8214506 82b1b1d 8214506 |
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 135 136 137 138 |
import React, { useState } from "react"
import { TokenChip } from "./TokenChip"
interface Word {
text: string
logprob: number
replacements: string[]
}
async function checkText(text: string): Promise<Word[]> {
await new Promise(resolve => setTimeout(resolve, 1000));
const words = text.split(/\b/)
return words.map(word => ({
text: word,
logprob: -word.length,
replacements: word.length < 4 ? [] : ["foo", "bar"]
}))
}
// Add a new Spinner component
const Spinner = () => (
<div className="spinner-overlay">
<div className="spinner"></div>
</div>
);
export default function App() {
const [threshold, setThreshold] = useState(-5.0)
const [context, setContext] = useState("")
const [wordlist, setWordlist] = useState("")
const [showWholePrompt, setShowWholePrompt] = useState(false)
const [text, setText] = useState("The cumbersomely quick brown fox jumps over the conspicuously lazy dog.")
const [mode, setMode] = useState<"edit" | "check">("edit")
const [words, setWords] = useState<Word[]>([])
const [isLoading, setIsLoading] = useState(false)
const toggleMode = async () => {
if (mode === "edit") {
setIsLoading(true)
try {
const checkedWords = await checkText(text)
setWords(checkedWords)
} finally {
setMode("check")
setIsLoading(false)
}
} else {
setMode("edit")
}
}
const handleReplace = (index: number, newToken: string) => {
const updatedWords = [...words]
updatedWords[index].text = newToken
setWords(updatedWords)
setText(updatedWords.map(w => w.text).join(""))
setMode("edit")
}
let result
if (mode === "edit") {
result = (
<div className="result-container">
{isLoading && <Spinner />}
<textarea value={text} onChange={e => setText(e.target.value)} />
</div>
)
} else {
result = (
<div className="result-container">
{isLoading && <Spinner />}
<div className="result">
{words.map((word, index) => (
<TokenChip
key={index}
token={word.text}
logprob={word.logprob}
threshold={threshold}
replacements={word.replacements}
onReplace={(newToken) => handleReplace(index, newToken)}
/>
))}
</div>
</div>
)
}
return (
<main>
<h1>GPTed</h1>
<details>
<summary>Advanced settings</summary>
<label>
<strong>Threshold:</strong> <input type="number" step="0.1" value={threshold} onChange={e => setThreshold(Number(e.target.value))} />
<small>
The <a href="https://en.wikipedia.org/wiki/Log_probability" target="_blank" rel="noreferrer">logprob</a> threshold.
Tokens with logprobs smaller than this will be marked red.
</small>
</label>
<label>
<strong>Context:</strong> <small>Context for the text, which can help GPT3 better rank certain words.</small>
<textarea placeholder="A short essay about picnics" value={context} onChange={e => setContext(e.target.value)} />
</label>
<label>
<strong>Dictionary:</strong>
<small>Known words or phrases. Helpful for uncommon or invented words and names.</small>
<textarea placeholder="jujubu eschaton Frodo Baggins" value={wordlist} onChange={e => setWordlist(e.target.value)} />
</label>
<label>
<strong>Show whole prompt:</strong> <input type="checkbox" checked={showWholePrompt} onChange={e => setShowWholePrompt(e.target.checked)} />
<small>
Show the whole prompt in the token view, instead of just your text. Mostly useful for debugging or curiosity.
</small>
</label>
</details>
<section id="inner">
{result}
<button onClick={toggleMode}>
{mode === "edit" ? "Check" : "Edit"}
</button>
<p>
<small>
Made by <a href="https://vgel.me">Theia Vogel</a> (<a href="https://twitter.com/voooooogel">@voooooogel</a>).
Made with Svelte, GPT-3, and transitively, most of the web.
<br />
This software is provided with absolutely no warranty.
</small>
</p>
</section>
</main>
)
}
|