incredibly advanced AI
This commit is contained in:
parent
5849342584
commit
06285689d7
97
src/index.js
97
src/index.js
@ -50,9 +50,95 @@ const handleOf = (thing, fn) => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const renderItem = x => x.quantity === 1 ? x.thing : `${x.quantity} ${handleOf(x.thing, pluralize.plural)}`
|
const PLURALS = [
|
||||||
|
["spoonful", "spoonfuls"],
|
||||||
|
["index", "indices"],
|
||||||
|
["lackey", "lackeys"],
|
||||||
|
["abiogenesis", "abiogeneses"],
|
||||||
|
["sheaf", "sheaves"],
|
||||||
|
["goose", "geese"],
|
||||||
|
["$DEITY", "$DEITIES"],
|
||||||
|
["ox", "oxen"],
|
||||||
|
["Category:English irregular plurals", "Categories:English irregular plurals"],
|
||||||
|
["enigma", "enigmas"],
|
||||||
|
["radix", "radixes"],
|
||||||
|
["water", "water"],
|
||||||
|
["funny", "funnies"],
|
||||||
|
["octopus", "octopoda"],
|
||||||
|
["the place in the world which is northernmost", "the places in the world which are northernmost"],
|
||||||
|
["datum", "data"],
|
||||||
|
["testbot", "testbots"],
|
||||||
|
["oil of vitriol", "oil of vitriol"],
|
||||||
|
["noun phrase", "noun phrases"],
|
||||||
|
["information", "information"],
|
||||||
|
["This phrase pluralizes as 'yellows'", "These phrases pluralize as 'yellows'"],
|
||||||
|
["fireman", "firemen"],
|
||||||
|
["potions of cryoapiocity", "potions of cryoapiocity"],
|
||||||
|
["sulfuric acid", "sulfuric acid"],
|
||||||
|
["dollar", "dollars"],
|
||||||
|
]
|
||||||
|
const PLURALS_KEEP_SAME = [
|
||||||
|
"mice",
|
||||||
|
"computers",
|
||||||
|
"lackeys",
|
||||||
|
"dodecahedra",
|
||||||
|
"those things which must not be seen",
|
||||||
|
"announcements",
|
||||||
|
"rotations"
|
||||||
|
]
|
||||||
|
const SINGULARS_KEEP_SAME = [
|
||||||
|
"mouse",
|
||||||
|
"computer",
|
||||||
|
"lackey",
|
||||||
|
"dodecahedron",
|
||||||
|
"that thing which must not be seen",
|
||||||
|
"announcement",
|
||||||
|
"rotation"
|
||||||
|
]
|
||||||
|
|
||||||
client.addListener("message", (nick, channel, message, ev) => {
|
const spliceIn = (xs, ys) => {
|
||||||
|
const locations = new Map(ys.map((y, i) => [Math.floor(xs.length * (i / ys.length)), y]))
|
||||||
|
const out = xs.map((x, i) => (locations.get(i) ? [x, locations.get(i)] : [x]))
|
||||||
|
const realOut = []
|
||||||
|
for (const x of out) {
|
||||||
|
for (const y of x) {
|
||||||
|
realOut.push(y)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return realOut
|
||||||
|
}
|
||||||
|
|
||||||
|
const queryLLM = async prompt => {
|
||||||
|
const res = await fetch("https://gpt.osmarks.net/v1/completions", {
|
||||||
|
body: JSON.stringify({
|
||||||
|
"max_tokens": 40,
|
||||||
|
"stop": ["\n"],
|
||||||
|
prompt
|
||||||
|
}),
|
||||||
|
method: "POST",
|
||||||
|
headers: {"Content-type": "application/json"}
|
||||||
|
})
|
||||||
|
const data = await res.json()
|
||||||
|
return data["choices"][0]["text"]
|
||||||
|
}
|
||||||
|
|
||||||
|
const deriveLLMMapping = (things, splice, fallback) => async input => {
|
||||||
|
const prompt = spliceIn(things, splice).map(([a, b]) => `${a} :: ${b}`).join("\n") + "\n" + input + " ::"
|
||||||
|
try {
|
||||||
|
const res = await queryLLM(prompt)
|
||||||
|
return res.trim()
|
||||||
|
} catch (e) {
|
||||||
|
console.warn("switched to fallback", e)
|
||||||
|
return fallback(input)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const pluralizer = deriveLLMMapping(PLURALS, PLURALS_KEEP_SAME.map(x => ([x, x])), pluralize.plural)
|
||||||
|
const singularizer = deriveLLMMapping(PLURALS.map(([a, b]) => ([b, a])), SINGULARS_KEEP_SAME.map(x => ([x, x])), pluralize.singular)
|
||||||
|
|
||||||
|
const renderItem = async x => x.quantity === 1 ? x.thing : `${x.quantity} ${await pluralizer(x.thing)}`
|
||||||
|
|
||||||
|
client.addListener("message", async (nick, channel, message, ev) => {
|
||||||
const e = /^<([^>]+)> (.*)$/.exec(message)
|
const e = /^<([^>]+)> (.*)$/.exec(message)
|
||||||
if (e) {
|
if (e) {
|
||||||
nick = e[1]
|
nick = e[1]
|
||||||
@ -100,13 +186,14 @@ client.addListener("message", (nick, channel, message, ev) => {
|
|||||||
qty = parseFloat(rqty)
|
qty = parseFloat(rqty)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
thing = handleOf(thing, pluralize.singular)
|
thing = await singularizer(thing)
|
||||||
const currQty = SQL`SELECT * FROM inventory WHERE thing = ${thing}`.get()?.quantity
|
const currQty = SQL`SELECT * FROM inventory WHERE thing = ${thing}`.get()?.quantity
|
||||||
if (currQty) { qty += currQty }
|
if (currQty) { qty += currQty }
|
||||||
qty = qty || 0
|
qty = qty || 0
|
||||||
SQL`INSERT OR REPLACE INTO inventory VALUES (${thing}, ${Date.now()}, ${qty})`.run()
|
SQL`INSERT OR REPLACE INTO inventory VALUES (${thing}, ${Date.now()}, ${qty})`.run()
|
||||||
console.log("attained", qty, thing)
|
console.log("attained", qty, thing)
|
||||||
client.say(channel, `I have ${renderItem({ thing, quantity: qty })}.`)
|
const hadThing = await renderItem({ thing, quantity: qty })
|
||||||
|
client.say(channel, `I have ${hadThing}.`)
|
||||||
}
|
}
|
||||||
} else if (cmd.startsWith("inv")) {
|
} else if (cmd.startsWith("inv")) {
|
||||||
const inv = SQL`SELECT * FROM inventory ORDER BY obtained_at DESC LIMIT 10`.all()
|
const inv = SQL`SELECT * FROM inventory ORDER BY obtained_at DESC LIMIT 10`.all()
|
||||||
@ -117,7 +204,7 @@ client.addListener("message", (nick, channel, message, ev) => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const messageContent = message.replace(/^(\s*[<\[][A-Za-z0-9_-]+[>\]]\s*)+/, "")
|
const messageContent = message.replace(/^(\s*[<\[][^\]>]+[>\]]\s*)+/, "")
|
||||||
sylhist = R.takeLast(3, R.append(syllables(messageContent), sylhist))
|
sylhist = R.takeLast(3, R.append(syllables(messageContent), sylhist))
|
||||||
mhist = R.takeLast(50, R.append(messageContent, mhist))
|
mhist = R.takeLast(50, R.append(messageContent, mhist))
|
||||||
if (R.equals(sylhist, [5, 7, 5])) {
|
if (R.equals(sylhist, [5, 7, 5])) {
|
||||||
|
Loading…
Reference in New Issue
Block a user