Skip to content

Instantly share code, notes, and snippets.

@Birch-san
Created June 24, 2026 01:21
Show Gist options
  • Select an option

  • Save Birch-san/bb0c556d5540b9879c12b5c666367ed4 to your computer and use it in GitHub Desktop.

Select an option

Save Birch-san/bb0c556d5540b9879c12b5c666367ed4 to your computer and use it in GitHub Desktop.
Infinite Craft in NAIScript, traditional coding style
export default {}
export interface Elem {
emoji: string
name: string
}
export interface ButtonModel {
held: boolean
elem: Elem
disabled: boolean
}
let chosen: Elem | undefined = undefined
// let canChoose = false
const initial: Elem[] = [
{emoji: '💧', name: 'Water'},
{emoji: '🔥', name: 'Fire'},
{emoji: '🌬️', name: 'Wind'},
{emoji: '🌍', name: 'Earth'},
// {emoji: '💨', name: 'Steam'},
]
let crafts: Elem[] = [...initial];
const elemSet: Set<string> = new Set(crafts.map(({name}) => name))
let buttonModels: ButtonModel[] = crafts.map(elem => ({elem, held: false, disabled: false}))
function fmtElem({ emoji, name }: Elem): string {
return `${emoji} ${name}`
}
function fmtEquation(left: Elem, right: Elem): string {
return `${fmtElem(left)} + ${fmtElem(right)} = `
}
const fewShot: Message[] = [
{
role: "user",
content: fmtEquation(
{emoji: '💧', name: 'Water'},
{emoji: '🔥', name: 'Fire'},
),
},
{
role: "assistant",
content: fmtElem({emoji: '💨', name: 'Steam'}),
},
{
role: "user",
content: fmtEquation(
{emoji: '💧', name: 'Water'},
{emoji: '🌬️', name: 'Wind'},
),
},
{
role: "assistant",
content: fmtElem({emoji: '🌧️', name: 'Rain'}),
},
{
role: "user",
content: fmtEquation(
{emoji: '🔥', name: 'Fire'},
{emoji: '🌍', name: 'Earth'},
),
},
{
role: "assistant",
content: fmtElem({emoji: 'Lava', name: '🌋'}),
},
]
async function craft(left: Elem, right: Elem) {
const { name: name0 } = left
const { name: name1 } = right
buttonModels = buttonModels.map(({elem}) => ({elem, held: elem.name in [name0, name1], disabled: true}))
await updateCraftPanel()
const prompt = fmtEquation(left, right)
// function cbk(choices: GenerationChoice[], final: boolean): void | string {
// api.v1.log(choices, final);
// }
const resp = await api.v1.generate(
[
...fewShot,
{
role: "user",
content: prompt,
},
] satisfies Message[],
{
model: "glm-4-6",
max_tokens: 50,
temperature: 0.8,
} satisfies GenerationParams,
undefined,// cbk,
"blocking",
)
const total = resp.choices.map(({text}) => text).join('')
api.v1.log(`Response: ${total}`)
// const match = /^(\p{Emoji_Presentation}+)\s+(.*)$/gu.exec(total)
const match = /^(\ud83c[\ud000-\udfff]|\ud83d[\ud000-\udfff]|\ud83e[\ud000-\udfff]+)\s+(.*)$/g.exec(total)
if (match) {
const [_, emoji, name] = match
const newCraft: Elem = {emoji, name}
const again = newCraft.name in elemSet
api.v1.log(`Crafted ${name} ${again ? "again" : "for the first time!"}`)
if (!again) {
elemSet.add(name)
crafts.push(newCraft)
buttonModels.push(({elem: newCraft, held: false, disabled: false}))
}
} else {
api.v1.log(`Couldn't parse response into an element.`)
}
chosen = undefined
buttonModels = buttonModels.map(({held, disabled, ...rest}) => ({held: false, disabled: false, ...rest}))
await updateCraftPanel()
}
async function choose(elem: Elem) {
// api.v1.log(`choose: ${JSON.stringify(elem, null, 2)}`);
const { emoji, name } = elem
if (chosen === undefined) {
chosen = elem
buttonModels = buttonModels.map(({elem, held, ...rest}) => ({elem, held: held || name === elem.name, ...rest}))
await updateCraftPanel()
} else if (chosen?.name === name) {
chosen = undefined
buttonModels = buttonModels.map(({held, ...rest}) => ({held: false, ...rest}))
await updateCraftPanel()
} else {
// craft
await craft(chosen, elem)
// chosen = undefined
// buttonModels = buttonModels.map(({held, disabled, ...rest}) => ({held: false, disabled: false, ...rest}))
// await updateCraftPanel()
}
// api.v1.log(`chose: ${JSON.stringify(elem, null, 2)}`);
// api.v1.log(`chosen: ${JSON.stringify(chosen, null, 2)}`);
}
function makeButton(buttonModel: ButtonModel): UIPartButton {
const { elem, held, disabled } = buttonModel
const { emoji, name } = elem
return {
type: "button",
// text: `${emoji} ${name}${held ? "!" : ""}`,
text: `${emoji} ${name}`,
callback: choose.bind(undefined, elem),
style: {
color: held ? 'rgb(19, 21, 44)' : undefined,
backgroundColor: held ? '#f4f3c6' : '#24253e',
...(disabled && {
cursor: 'not-allowed',
pointerEvents: 'none',
})
},
}
}
async function updateCraftPanel() {
// api.v1.log(`buttonModels: ${JSON.stringify(buttonModels, null, 2)}`);
const panelContent: UIPartRow[] = [
{
type: "row",
content: buttonModels.map(buttonModel => makeButton(buttonModel)),
},
];
// api.v1.log(`panelContent: ${JSON.stringify(panelContent, null, 2)}`);
await api.v1.ui.register([
{
type: "scriptPanel",
id: "craftPanel",
name: "Craft",
iconId: "file-text",
content: [
{
type: "container",
content: panelContent,
style: {
height: "300px",
width: "100%",
display: "flex",
flexDirection: "column",
},
} satisfies UIPartContainer,
],
} satisfies UIExtensionScriptPanel,
]);
}
// Initialize - load notes from storage
async function init() {
// crafts = (await api.v1.storage.get("crafts")) || [];
await updateCraftPanel();
}
// Initialize
(async () => {
// Register the initial panel
await api.v1.ui.register([
{
type: "scriptPanel",
id: "craftPanel",
name: "Craft",
iconId: "file-text",
content: [],
} satisfies UIExtensionScriptPanel,
]);
api.v1.log("Craft panel registered");
await init();
api.v1.log("Craft panel initialized successfully!");
})();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment