/// import { Cell, generateObject, handler, ifElse, lift, NAME, recipe, str, toSchema, UI, } from "commontools"; interface InputState { number: Cell; } interface NumberStory { number: number; story: string; title: string; storyOrigin: string; seeAlso: number[]; imagePrompt: string; } interface SetNumberEvent { number: Cell; n: number; } // Handler to increment the number const adder = handler((_, state) => { state.number.set(state.number.get() + 1); }); // Handler to set a specific number const setNumber = handler((_, state: { number: Cell; n: number }) => { state.number.set(state.n); }); // Generate the prompt for the LLM const generatePrompt = lift(({ number }: { number: number }) => { return { prompt: `You are the parent of a young child who loves to learn about numbers. Luckily for your child, you are a historian of numbers and when the child says a number you make up an interesting story about it, including the history of the number. The child is currently at ${number}. Also return a recommendation for other numbers that might be interesting to the child to learn about next.`, schema: outputSchema, }; }); // Generate an image URL from the prompt const generateImageUrl = lift(({ imagePrompt }: { imagePrompt: string }) => { return `/api/ai/img?prompt=${encodeURIComponent(imagePrompt)}`; }); const inputSchema = toSchema({ default: { number: 0 }, }); const outputSchema = toSchema(); export default recipe(inputSchema, outputSchema, (cell) => { // Use generateObject to get structured data from the LLM const { result: object, pending } = generateObject( generatePrompt({ number: cell.number }), ); const imageUrl = generateImageUrl({ imagePrompt: object?.imagePrompt || "robot thinking", }); return { [NAME]: str`Number Story: ${object?.title || "Loading..."}`, [UI]: (
Current number: {cell.number} (click to increment) {ifElse( pending,

Generating story...

,

{object?.title}

{object?.story}

{object?.storyOrigin}

See also these interesting numbers:

    {object?.seeAlso?.map((n: number) => (
  • {n}
  • ))}
, )}
), number: cell.number, ...object, }; });