import { detectFileType } from "@noya-app/noya-utils"; import { Type } from "@sinclair/typebox"; import { describe, expect, it } from "bun:test"; import { indexedDB } from "fake-indexeddb"; import { NoyaManager } from "../NoyaManager"; import { localStorageSync } from "../sync/localStorageSync"; globalThis.indexedDB = indexedDB; function createNoyaManager() { return new NoyaManager(null); } describe("localStorageSync AI generation", () => { it("returns a schema-valid default object", async () => { const noyaManager = createNoyaManager(); const cleanup = localStorageSync({ key: "test-local-ai-generation", })({ noyaManager }); const result = await noyaManager.aiManager.generateObject({ prompt: "Create a todo", schema: Type.Object({ title: Type.String({ default: "Local todo" }), completed: Type.Boolean(), tags: Type.Array(Type.String()), }), }); expect(result).toEqual({ title: "Local todo", completed: false, tags: [], }); cleanup(); }); it("returns deterministic text and image stubs", async () => { const noyaManager = createNoyaManager(); const cleanup = localStorageSync({ key: "test-local-ai-text-image-generation", })({ noyaManager }); const text = await noyaManager.aiManager.generateText({ prompt: "Write a todo", model: "custom-text-model", temperature: 0.2, topK: 40, presencePenalty: 0.1, frequencyPenalty: 0.2, seed: 42, }); const image = await noyaManager.aiManager.generateImage({ prompt: "Draw a todo", model: "custom-image-model", }); expect(text).toBe(""); expect(image.mediaType).toBe("image/png"); expect(detectFileType(image.data)).toBe("image/png"); cleanup(); }); it("spoofs incremental object and text streams", async () => { const noyaManager = createNoyaManager(); const cleanup = localStorageSync({ key: "test-local-ai-streaming", })({ noyaManager }); const objectResult = noyaManager.aiManager.streamObject({ prompt: "Create a todo", schema: Type.Object({ title: Type.String({ default: "Local todo" }), completed: Type.Boolean(), }), }); const textResult = noyaManager.aiManager.streamText({ prompt: "Write a todo", }); expect(await collect(objectResult.partialObjectStream)).toEqual([ {}, { title: "Local todo" }, { title: "Local todo", completed: false }, ]); expect(await objectResult.object).toEqual({ title: "Local todo", completed: false, }); expect(await collect(textResult.textStream)).toEqual([ "Local AI ", "generated ", "text.", ]); expect(await textResult.text).toBe("Local AI generated text."); cleanup(); }); }); async function collect(iterable: AsyncIterable): Promise { const values: T[] = []; for await (const value of iterable) values.push(value); return values; }