@kubuild/ai 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (68) hide show
  1. package/LICENSE +21 -0
  2. package/dist/chunk-27AY2KBI.js +500 -0
  3. package/dist/chunk-27AY2KBI.js.map +1 -0
  4. package/dist/chunk-JY4NHD3Q.js +227 -0
  5. package/dist/chunk-JY4NHD3Q.js.map +1 -0
  6. package/dist/chunk-UH24LHRY.js +443 -0
  7. package/dist/chunk-UH24LHRY.js.map +1 -0
  8. package/dist/client/ai-client.d.ts +59 -0
  9. package/dist/client/ai-client.d.ts.map +1 -0
  10. package/dist/client/index.cjs +254 -0
  11. package/dist/client/index.cjs.map +1 -0
  12. package/dist/client/index.d.ts +2 -0
  13. package/dist/client/index.d.ts.map +1 -0
  14. package/dist/client/index.js +9 -0
  15. package/dist/client/index.js.map +1 -0
  16. package/dist/core/index.d.ts +3 -0
  17. package/dist/core/index.d.ts.map +1 -0
  18. package/dist/core/normalizer.d.ts +9 -0
  19. package/dist/core/normalizer.d.ts.map +1 -0
  20. package/dist/core/prompt-compiler.d.ts +10 -0
  21. package/dist/core/prompt-compiler.d.ts.map +1 -0
  22. package/dist/index.cjs +468 -0
  23. package/dist/index.cjs.map +1 -0
  24. package/dist/index.d.ts +3 -0
  25. package/dist/index.d.ts.map +1 -0
  26. package/dist/index.js +23 -0
  27. package/dist/index.js.map +1 -0
  28. package/dist/react/index.cjs +584 -0
  29. package/dist/react/index.cjs.map +1 -0
  30. package/dist/react/index.d.ts +3 -0
  31. package/dist/react/index.d.ts.map +1 -0
  32. package/dist/react/index.js +336 -0
  33. package/dist/react/index.js.map +1 -0
  34. package/dist/react/use-ai-chat.d.ts +63 -0
  35. package/dist/react/use-ai-chat.d.ts.map +1 -0
  36. package/dist/react/use-ai-generator.d.ts +19 -0
  37. package/dist/react/use-ai-generator.d.ts.map +1 -0
  38. package/dist/server/adapters/anthropic.d.ts +30 -0
  39. package/dist/server/adapters/anthropic.d.ts.map +1 -0
  40. package/dist/server/adapters/base.d.ts +2 -0
  41. package/dist/server/adapters/base.d.ts.map +1 -0
  42. package/dist/server/adapters/custom.d.ts +18 -0
  43. package/dist/server/adapters/custom.d.ts.map +1 -0
  44. package/dist/server/adapters/gemini.d.ts +22 -0
  45. package/dist/server/adapters/gemini.d.ts.map +1 -0
  46. package/dist/server/adapters/index.cjs +529 -0
  47. package/dist/server/adapters/index.cjs.map +1 -0
  48. package/dist/server/adapters/index.d.ts +6 -0
  49. package/dist/server/adapters/index.d.ts.map +1 -0
  50. package/dist/server/adapters/index.js +13 -0
  51. package/dist/server/adapters/index.js.map +1 -0
  52. package/dist/server/adapters/openai.d.ts +26 -0
  53. package/dist/server/adapters/openai.d.ts.map +1 -0
  54. package/dist/server/adapters/stream-utils.d.ts +12 -0
  55. package/dist/server/adapters/stream-utils.d.ts.map +1 -0
  56. package/dist/server/engine.d.ts +59 -0
  57. package/dist/server/engine.d.ts.map +1 -0
  58. package/dist/server/handler.d.ts +66 -0
  59. package/dist/server/handler.d.ts.map +1 -0
  60. package/dist/server/index.cjs +1824 -0
  61. package/dist/server/index.cjs.map +1 -0
  62. package/dist/server/index.d.ts +4 -0
  63. package/dist/server/index.d.ts.map +1 -0
  64. package/dist/server/index.js +890 -0
  65. package/dist/server/index.js.map +1 -0
  66. package/dist/types.d.ts +184 -0
  67. package/dist/types.d.ts.map +1 -0
  68. package/package.json +94 -0
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/server/engine.ts","../../src/server/handler.ts"],"sourcesContent":["import { PageDocument, Node, DocumentMetadataSchema, DocumentMetadata } from '@kubuild/schema';\nimport type {\n KubuildAiEngineOptions,\n AiGeneratePageRequest,\n AiGenerateSectionRequest,\n AiRefactorNodeRequest,\n AiChatRequest,\n AiChatResponse,\n AiChatMessage,\n AiGenerateResponse,\n AiCompiledComponentSpec,\n AiStreamEvent,\n} from '../types';\nimport {\n compileComponentCatalog,\n buildSystemPrompt,\n buildJsonSchemaForMode,\n} from '../core/prompt-compiler';\nimport {\n extractJsonFromResponse,\n normalizeAndValidatePageDocument,\n normalizeAndValidateSectionNode,\n normalizeAndValidateRefactoredNode,\n} from '../core/normalizer';\n\ninterface PlannedSection {\n type: string;\n title: string;\n prompt: string;\n}\n\ninterface PagePlan {\n title?: string;\n description?: string;\n pageStyles?: Node['styles'];\n sections?: PlannedSection[];\n} \n\nexport class KubuildAiEngine {\n private options: KubuildAiEngineOptions;\n private catalog: AiCompiledComponentSpec[];\n\n constructor(options: KubuildAiEngineOptions) {\n if (!options.adapter) {\n throw new Error('KubuildAiEngine requires an adapter instance');\n }\n this.options = options;\n this.catalog = compileComponentCatalog(options.registry);\n }\n\n get adapterName(): string {\n return this.options.adapter.name;\n }\n\n refreshCatalog(): void {\n this.catalog = compileComponentCatalog(this.options.registry);\n }\n\n private log(level: 'info' | 'warn' | 'error' | 'debug', message: string, meta?: unknown): void {\n if (this.options.logger) {\n this.options.logger(level, message, meta);\n } else if (this.options.debug) {\n const ts = new Date().toISOString();\n console.log(`[KUBUILD-AI ${level.toUpperCase()}] [${ts}] ${message}`, meta !== undefined ? meta : '');\n }\n }\n\n async generatePage(\n request: AiGeneratePageRequest,\n context?: { signal?: AbortSignal },\n ): Promise<AiGenerateResponse<PageDocument>> {\n let rawText = '';\n try {\n this.log('info', `Generating full page for prompt: \"${request.prompt}\"`);\n const systemPrompt = buildSystemPrompt({\n catalog: this.catalog,\n mode: 'full-page',\n prefix: this.options.systemPromptPrefix,\n stylePreference: request.stylePreference,\n });\n\n let userPrompt = `User Request: ${request.prompt}`;\n if (request.tone) userPrompt += `\\nTone: ${request.tone}`;\n if (request.locale) userPrompt += `\\nLanguage/Locale: ${request.locale}`;\n\n const jsonSchema = buildJsonSchemaForMode('full-page');\n\n const result = await this.options.adapter.generate({\n systemPrompt,\n userPrompt,\n jsonSchema,\n signal: context?.signal,\n });\n\n this.log('debug', 'Raw model response (generatePage)', result.text);\n\n rawText = result.text;\n const rawJson = extractJsonFromResponse(rawText);\n const document = normalizeAndValidatePageDocument(\n rawJson,\n this.options.securityLimits,\n );\n\n // Merge user requested metadata if given\n if (request.metadata) {\n document.metadata = DocumentMetadataSchema.parse({\n ...document.metadata,\n ...request.metadata,\n });\n }\n\n this.log(\n 'info',\n `Full page successfully generated: \"${document.metadata?.title || 'Untitled'}\" (${document.document.children?.length || 0} sections)`,\n );\n\n return {\n success: true,\n data: document,\n usage: result.usage,\n rawModelResponse: rawText,\n };\n } catch (err: unknown) {\n const message = err instanceof Error ? err.message : String(err);\n this.log('error', `Generation failed: ${message}`);\n return {\n success: false,\n error: {\n code: 'GENERATION_ERROR',\n message,\n },\n rawModelResponse: rawText || undefined,\n };\n }\n }\n\n async generateSection(\n request: AiGenerateSectionRequest,\n context?: { signal?: AbortSignal },\n ): Promise<AiGenerateResponse<Node>> {\n let rawText = '';\n try {\n const systemPrompt = buildSystemPrompt({\n catalog: this.catalog,\n mode: 'section',\n prefix: this.options.systemPromptPrefix,\n stylePreference: request.stylePreference,\n });\n\n let userPrompt = `Generate a single section node for: ${request.prompt}`;\n if (request.targetSectionType) {\n userPrompt += `\\nTarget Section Purpose: ${request.targetSectionType}`;\n }\n if (request.parentContext) {\n userPrompt += `\\nSurrounding Page Context: ${request.parentContext}`;\n }\n\n const jsonSchema = buildJsonSchemaForMode('section');\n\n const result = await this.options.adapter.generate({\n systemPrompt,\n userPrompt,\n jsonSchema,\n signal: context?.signal,\n });\n\n this.log('debug', 'Raw model response (generateSection)', result.text);\n\n rawText = result.text;\n const rawJson = extractJsonFromResponse(rawText);\n const sectionNode = normalizeAndValidateSectionNode(\n rawJson,\n this.options.securityLimits,\n );\n\n return {\n success: true,\n data: sectionNode,\n usage: result.usage,\n rawModelResponse: rawText,\n };\n } catch (err: unknown) {\n const message = err instanceof Error ? err.message : String(err);\n return {\n success: false,\n error: {\n code: 'SECTION_GENERATION_ERROR',\n message,\n },\n rawModelResponse: rawText || undefined,\n };\n }\n }\n\n async refactorNode(\n request: AiRefactorNodeRequest,\n context?: { signal?: AbortSignal },\n ): Promise<AiGenerateResponse<Node>> {\n let rawText = '';\n try {\n const systemPrompt = buildSystemPrompt({\n catalog: this.catalog,\n mode: 'refactor',\n prefix: this.options.systemPromptPrefix,\n stylePreference: request.stylePreference,\n });\n\n const userPrompt = `Instruction: ${request.instruction}\\n\\nCurrent Node:\\n${JSON.stringify(request.node, null, 2)}`;\n const jsonSchema = buildJsonSchemaForMode('refactor');\n\n const result = await this.options.adapter.generate({\n systemPrompt,\n userPrompt,\n jsonSchema,\n signal: context?.signal,\n });\n\n rawText = result.text;\n const rawJson = extractJsonFromResponse(rawText);\n const updatedNode = normalizeAndValidateRefactoredNode(\n rawJson,\n request.node,\n this.options.securityLimits,\n );\n\n return {\n success: true,\n data: updatedNode,\n usage: result.usage,\n rawModelResponse: rawText,\n };\n } catch (err: unknown) {\n const message = err instanceof Error ? err.message : String(err);\n return {\n success: false,\n error: {\n code: 'REFACTOR_ERROR',\n message,\n },\n rawModelResponse: rawText || undefined,\n };\n }\n }\n\n /**\n * Progressive Section Streaming Generator.\n * Emits structured SSE events: status -> metadata -> section (one by one) -> complete.\n */\n async *streamPage(\n request: AiGeneratePageRequest,\n context?: { signal?: AbortSignal },\n ): AsyncIterable<AiStreamEvent> {\n try {\n this.log('info', `[SSE] Starting streamPage for prompt: \"${request.prompt}\"`);\n\n yield {\n type: 'status',\n message: 'Analyzing requirements and planning page sections...',\n };\n\n // 1. Plan page sections\n const planSystemPrompt = `\nYou are a web architect for the KUBUILD page builder.\nGiven the user's prompt, plan the website structure. Output pure JSON (no markdown fences, no explanatory text):\n{\n \"title\": \"<Page Title>\",\n \"description\": \"<Page Description>\",\n \"pageStyles\": {\n \"base\": {\n \"backgroundColor\": \"#ffffff\",\n \"fontFamily\": \"Inter, system-ui, sans-serif\",\n \"color\": \"#111827\",\n \"minHeight\": \"100vh\"\n }\n },\n \"sections\": [\n {\n \"type\": \"<hero|features|pricing|testimonials|cta|contact|footer>\",\n \"title\": \"<Brief title>\",\n \"prompt\": \"<Detailed prompt for generating this specific section with components, layout, and content>\"\n }\n ]\n}\nPlan 3 cohesive, essential sections (e.g., hero, features, and cta) that fulfill the request.\n`;\n\n let planUserPrompt = `User Request: ${request.prompt}`;\n if (request.stylePreference) {\n planUserPrompt += `\\nStyle Preference: ${request.stylePreference}`;\n }\n if (request.tone) planUserPrompt += `\\nTone: ${request.tone}`;\n if (request.locale) planUserPrompt += `\\nLocale: ${request.locale}`;\n\n this.log('info', '[SSE] Generating website layout plan...');\n const planResult = await this.options.adapter.generate({\n systemPrompt: planSystemPrompt,\n userPrompt: planUserPrompt,\n signal: context?.signal,\n });\n\n this.log('debug', '[SSE] Raw plan response from model', planResult.text);\n\n let plan: PagePlan;\n try {\n plan = extractJsonFromResponse(planResult.text) as PagePlan;\n this.log('debug', '[SSE] Parsed plan successfully', plan);\n } catch (parseErr) {\n this.log('warn', '[SSE] Failed to parse plan JSON, using fallback plan', parseErr);\n // Fallback default plan if JSON parse failed\n plan = {\n title: 'AI Generated Page',\n description: 'Generated by KUBUILD AI',\n sections: [\n { type: 'hero', title: 'Hero Banner', prompt: `Hero section for: ${request.prompt}` },\n { type: 'features', title: 'Key Features', prompt: `Features grid for: ${request.prompt}` },\n { type: 'cta', title: 'Call To Action', prompt: `Call to action section for: ${request.prompt}` },\n ],\n };\n }\n\n const sectionsToGenerate = Array.isArray(plan.sections) && plan.sections.length > 0\n ? plan.sections\n : [\n { type: 'hero', title: 'Hero Section', prompt: `Hero banner for: ${request.prompt}` },\n { type: 'features', title: 'Features', prompt: `Features grid for: ${request.prompt}` },\n { type: 'cta', title: 'Call To Action', prompt: `CTA section for: ${request.prompt}` },\n ];\n\n const metadata: DocumentMetadata = DocumentMetadataSchema.parse({\n title: plan.title || 'AI Generated Page',\n description: plan.description || 'Generated by KUBUILD AI',\n author: 'KUBUILD AI',\n tags: ['ai-generated', 'progressive-stream'],\n category: 'landing',\n version: '1.0.0',\n ...(request.metadata || {}),\n });\n\n const rootPageNode: Node = {\n id: 'root-page',\n type: 'page',\n styles: plan.pageStyles || {\n base: {\n backgroundColor: '#ffffff',\n fontFamily: 'Inter, system-ui, sans-serif',\n color: '#111827',\n minHeight: '100vh',\n },\n },\n children: [],\n };\n\n // 2. Emit initial metadata so canvas can render initial empty page immediately!\n this.log('info', `[SSE] Emitting metadata: \"${metadata.title}\"`);\n yield {\n type: 'metadata',\n metadata,\n rootPageNode,\n };\n\n this.log(\n 'info',\n `[SSE] Plan ready with ${sectionsToGenerate.length} sections: ${sectionsToGenerate.map((s) => s.title).join(', ')}`,\n );\n yield {\n type: 'status',\n message: `Plan ready with ${sectionsToGenerate.length} sections: ${sectionsToGenerate.map((s) => s.title).join(', ')}`,\n };\n\n // 3. Sequentially generate each section and stream it!\n const completedSections: Node[] = [];\n const total = sectionsToGenerate.length;\n\n for (let i = 0; i < total; i++) {\n if (context?.signal?.aborted) {\n this.log('warn', '[SSE] Streaming aborted by client signal');\n throw new Error('Streaming aborted by client');\n }\n\n const plannedSec = sectionsToGenerate[i];\n this.log(\n 'info',\n `[SSE] Generating section ${i + 1}/${total} [${plannedSec.type}]: \"${plannedSec.title}\"`,\n );\n yield {\n type: 'status',\n message: `Generating section ${i + 1}/${total} (${plannedSec.title})...`,\n };\n\n const secRes = await this.generateSection(\n {\n prompt: plannedSec.prompt,\n stylePreference: request.stylePreference,\n targetSectionType: plannedSec.type,\n parentContext: `Website: ${plan.title}. Previous sections: ${sectionsToGenerate.slice(0, i).map((s) => s.title).join(', ')}`,\n },\n { signal: context?.signal },\n );\n\n if (secRes.success && secRes.data) {\n this.log(\n 'info',\n `[SSE] Section ${i + 1}/${total} generated successfully: [${secRes.data.id || secRes.data.type}]`,\n );\n completedSections.push(secRes.data);\n yield {\n type: 'section',\n index: i,\n total,\n section: secRes.data,\n };\n } else {\n this.log('error', `[SSE] Section ${i + 1}/${total} failed`, secRes.error?.message);\n }\n }\n\n if (completedSections.length === 0) {\n this.log('error', '[SSE] All sections failed to generate.');\n yield {\n type: 'error',\n error: {\n code: 'STREAM_GENERATION_FAILED',\n message: 'All sections failed to generate. Please check server logs or retry.',\n },\n };\n return;\n }\n\n // 4. Assemble final document and emit complete event\n const finalDocument: PageDocument = {\n schema: 'stora.page',\n version: '1.0.0',\n metadata,\n document: {\n ...rootPageNode,\n children: completedSections,\n } as PageDocument['document'],\n };\n\n this.log(\n 'info',\n `[SSE] All ${completedSections.length} sections generated. Emitting complete event.`,\n );\n yield {\n type: 'complete',\n document: finalDocument,\n };\n } catch (err: unknown) {\n const message = err instanceof Error ? err.message : String(err);\n this.log('error', `[SSE] Streaming failed: ${message}`);\n yield {\n type: 'error',\n error: {\n code: 'STREAM_ERROR',\n message,\n },\n };\n }\n }\n\n /**\n * Builds the system/user prompt pair shared by `chat()` and `chatStream()` — the exact\n * same document/selection grounding is used regardless of whether the response is\n * streamed token-by-token or returned as a single request/response (STORA-515).\n */\n private buildChatPrompt(request: AiChatRequest): { systemPrompt: string; userPrompt: string } {\n let systemPrompt = `You are the KUBUILD AI Assistant — an expert web designer, developer, and page architecture consultant.\nYour role is to assist users with creating, designing, refining, and understanding web pages built with the KUBUILD builder.\nAnswer questions directly, concisely, and helpfully using friendly professional tone and markdown formatting.\n\n### Available KUBUILD Components:\n${this.catalog.map((c) => `- **${c.type}** (${c.category}): ${c.label}${c.description ? ` — ${c.description}` : ''}`).join('\\n')}\n`;\n\n if (this.options.systemPromptPrefix) {\n systemPrompt = `${this.options.systemPromptPrefix}\\n\\n${systemPrompt}`;\n }\n\n if (request.systemPrompt) {\n systemPrompt += `\\nAdditional Context:\\n${request.systemPrompt}`;\n }\n\n if (request.currentDocument) {\n const doc = request.currentDocument;\n const sections = doc.document?.children || [];\n const sectionSummary = sections\n .map((s, idx) => `Section ${idx + 1}: id=\"${s.id}\", type=\"${s.type}\", title=\"${(s.props?.title as string) || 'untitled'}\", childrenCount=${s.children?.length || 0}`)\n .join('\\n');\n\n systemPrompt += `\\n### Current Page in Builder Canvas:\n- Title: ${doc.metadata?.title || 'Untitled Page'}\n- Description: ${doc.metadata?.description || 'N/A'}\n- Total Sections: ${sections.length}\n- Sections Summary:\n${sectionSummary || '(Canvas is currently empty)'}\n`;\n }\n\n if (request.selectedNodeId) {\n systemPrompt += `\\nCurrently Selected Component Node ID: \"${request.selectedNodeId}\"`;\n }\n\n // Extract last user message\n const lastUserMsg = [...request.messages].reverse().find((m) => m.role === 'user');\n const userPrompt = lastUserMsg?.content || 'Hello';\n\n return { systemPrompt, userPrompt };\n }\n\n /**\n * Conversational Assistant / Q&A.\n * Can discuss web design, explain KUBUILD components, review current page,\n * suggest improvements, or recommend copywriting.\n *\n * Single request/response — unchanged since before STORA-515. See `chatStream()` for\n * the token-level streaming variant.\n */\n async chat(\n request: AiChatRequest,\n context?: { signal?: AbortSignal },\n ): Promise<AiGenerateResponse<AiChatResponse>> {\n let rawText = '';\n try {\n if (!request.messages || !Array.isArray(request.messages) || request.messages.length === 0) {\n return {\n success: false,\n error: {\n code: 'INVALID_CHAT_REQUEST',\n message: '\"messages\" array is required and must not be empty',\n },\n };\n }\n\n this.log('info', `Processing chat turn with ${request.messages.length} messages`);\n\n const { systemPrompt, userPrompt } = this.buildChatPrompt(request);\n\n const result = await this.options.adapter.generate({\n systemPrompt,\n userPrompt,\n messages: request.messages,\n signal: context?.signal,\n });\n\n rawText = result.text.trim();\n\n const assistantMessage: AiChatMessage = {\n role: 'assistant',\n content: rawText,\n timestamp: Date.now(),\n };\n\n return {\n success: true,\n data: {\n message: assistantMessage,\n },\n usage: result.usage,\n rawModelResponse: rawText,\n };\n } catch (err: unknown) {\n const message = err instanceof Error ? err.message : String(err);\n this.log('error', `Chat failed: ${message}`);\n return {\n success: false,\n error: {\n code: 'CHAT_ERROR',\n message,\n },\n rawModelResponse: rawText || undefined,\n };\n }\n }\n\n /**\n * Token-level streaming variant of `chat()` (STORA-515). Emits `chat-chunk` events as\n * partial text arrives, then a terminal `chat-complete` event with the fully assembled\n * assistant message — the same `AsyncIterable<AiStreamEvent>` mechanism `streamPage`\n * already uses, so it can be piped over SSE by `createAiHandler`/consumed by\n * `KubuildAiClient` with no separate transport.\n *\n * When the configured adapter does not implement `generateStream` (e.g. the generic\n * custom/HTTP adapter), this falls back to a single non-streaming `generate()` call and\n * emits the entire response as one `chat-chunk`, so callers never see an error just\n * because the underlying provider can't stream — only a less granular update cadence.\n */\n async *chatStream(\n request: AiChatRequest,\n context?: { signal?: AbortSignal },\n ): AsyncIterable<AiStreamEvent> {\n try {\n if (!request.messages || !Array.isArray(request.messages) || request.messages.length === 0) {\n yield {\n type: 'error',\n error: {\n code: 'INVALID_CHAT_REQUEST',\n message: '\"messages\" array is required and must not be empty',\n },\n };\n return;\n }\n\n this.log(\n 'info',\n `[SSE] Starting chatStream with ${request.messages.length} messages (adapter: ${this.options.adapter.name})`,\n );\n\n const { systemPrompt, userPrompt } = this.buildChatPrompt(request);\n\n let accumulated = '';\n let usage: AiGenerateResponse<AiChatResponse>['usage'];\n\n if (typeof this.options.adapter.generateStream === 'function') {\n const generator = this.options.adapter.generateStream({\n systemPrompt,\n userPrompt,\n messages: request.messages,\n signal: context?.signal,\n });\n\n while (true) {\n const { value, done } = await generator.next();\n if (done) {\n usage = value?.usage;\n break;\n }\n accumulated += value;\n yield { type: 'chat-chunk', delta: value, content: accumulated };\n }\n } else {\n this.log(\n 'debug',\n `Adapter \"${this.options.adapter.name}\" has no generateStream; falling back to non-streaming chat`,\n );\n const result = await this.options.adapter.generate({\n systemPrompt,\n userPrompt,\n messages: request.messages,\n signal: context?.signal,\n });\n accumulated = result.text;\n usage = result.usage;\n yield { type: 'chat-chunk', delta: accumulated, content: accumulated };\n }\n\n const assistantMessage: AiChatMessage = {\n role: 'assistant',\n content: accumulated.trim(),\n timestamp: Date.now(),\n };\n\n this.log('info', '[SSE] Chat stream completed', usage);\n yield { type: 'chat-complete', message: assistantMessage };\n } catch (err: unknown) {\n const message = err instanceof Error ? err.message : String(err);\n this.log('error', `[SSE] Chat streaming failed: ${message}`);\n yield {\n type: 'error',\n error: {\n code: 'CHAT_STREAM_ERROR',\n message,\n },\n };\n }\n }\n}\n","import type { KubuildAiEngine } from './engine';\nimport type { PageDocument } from '@kubuild/schema';\nimport type {\n AiGeneratePageRequest,\n AiGenerateSectionRequest,\n AiRefactorNodeRequest,\n AiChatMessage,\n AiGenerateResponse,\n AiGenerationMode,\n} from '../types';\n\nexport interface AiApiRequestBody {\n mode?: AiGenerationMode;\n prompt?: string;\n stylePreference?: string;\n tone?: string;\n locale?: string;\n metadata?: AiGeneratePageRequest['metadata'];\n targetSectionType?: string;\n parentContext?: string;\n node?: AiRefactorNodeRequest['node'];\n instruction?: string;\n stream?: boolean;\n messages?: AiChatMessage[];\n currentDocument?: PageDocument;\n selectedNodeId?: string;\n}\n\nexport async function processAiRequest(\n engine: KubuildAiEngine,\n body: unknown,\n signal?: AbortSignal,\n): Promise<{ status: number; response: AiGenerateResponse<unknown> }> {\n if (!body || typeof body !== 'object') {\n return {\n status: 400,\n response: {\n success: false,\n error: {\n code: 'BAD_REQUEST',\n message: 'Request body must be a valid JSON object',\n },\n },\n };\n }\n\n const payload = body as AiApiRequestBody;\n const mode = payload.mode || 'full-page';\n\n if (mode === 'full-page') {\n if (!payload.prompt || typeof payload.prompt !== 'string') {\n return {\n status: 400,\n response: {\n success: false,\n error: {\n code: 'INVALID_PROMPT',\n message: '\"prompt\" is required for full-page generation',\n },\n },\n };\n }\n const result = await engine.generatePage(\n {\n prompt: payload.prompt,\n stylePreference: payload.stylePreference,\n tone: payload.tone,\n locale: payload.locale,\n metadata: payload.metadata,\n },\n { signal },\n );\n return {\n status: result.success ? 200 : 500,\n response: result,\n };\n }\n\n if (mode === 'section') {\n if (!payload.prompt || typeof payload.prompt !== 'string') {\n return {\n status: 400,\n response: {\n success: false,\n error: {\n code: 'INVALID_PROMPT',\n message: '\"prompt\" is required for section generation',\n },\n },\n };\n }\n const result = await engine.generateSection(\n {\n prompt: payload.prompt,\n stylePreference: payload.stylePreference,\n targetSectionType: payload.targetSectionType,\n parentContext: payload.parentContext,\n },\n { signal },\n );\n return {\n status: result.success ? 200 : 500,\n response: result,\n };\n }\n\n if (mode === 'refactor') {\n if (!payload.node || !payload.instruction) {\n return {\n status: 400,\n response: {\n success: false,\n error: {\n code: 'INVALID_REFACTOR_PARAMS',\n message: '\"node\" and \"instruction\" are required for refactoring',\n },\n },\n };\n }\n const result = await engine.refactorNode(\n {\n node: payload.node,\n instruction: payload.instruction,\n stylePreference: payload.stylePreference,\n },\n { signal },\n );\n return {\n status: result.success ? 200 : 500,\n response: result,\n };\n }\n\n if (mode === 'chat') {\n if (!payload.messages || !Array.isArray(payload.messages) || payload.messages.length === 0) {\n return {\n status: 400,\n response: {\n success: false,\n error: {\n code: 'INVALID_CHAT_PARAMS',\n message: '\"messages\" array is required and must not be empty for chat mode',\n },\n },\n };\n }\n const result = await engine.chat(\n {\n messages: payload.messages,\n currentDocument: payload.currentDocument,\n selectedNodeId: payload.selectedNodeId,\n },\n { signal },\n );\n return {\n status: result.success ? 200 : 500,\n response: result,\n };\n }\n\n return {\n status: 400,\n response: {\n success: false,\n error: {\n code: 'UNKNOWN_MODE',\n message: `Unsupported mode: ${String(mode)}. Supported modes: 'full-page', 'section', 'refactor', 'chat'`,\n },\n },\n };\n}\n\n/**\n * Options for {@link createAiHandler} (STORA-519).\n */\nexport interface CreateAiHandlerOptions {\n /**\n * Optional hook invoked with the raw incoming `Request` before it ever reaches the\n * engine/provider — the place to plug in host-owned auth and/or rate-limiting without\n * forking the handler.\n *\n * - Return a `Response` (or a Promise resolving to one) to reject/short-circuit the\n * request — e.g. `new Response(..., { status: 401 })` or `429` — that response is\n * returned as-is and the engine/provider is never invoked.\n * - Return `void`/`undefined` (or a Promise resolving to that) to allow the request to\n * continue through the normal handler logic unchanged.\n *\n * Omitting this option entirely preserves the exact pre-STORA-519 behavior.\n */\n beforeRequest?: (request: Request) => Promise<Response | void> | Response | void;\n}\n\n/**\n * Creates a standard Web Fetch API Request handler with optional SSE streaming support.\n *\n * Plug-and-play for Next.js App Router (route.ts), SvelteKit, Remix, Astro, Bun, etc.\n *\n * Example:\n * ```ts\n * export const POST = createAiHandler(engine);\n * ```\n *\n * Example with an auth/rate-limit hook (STORA-519):\n * ```ts\n * export const POST = createAiHandler(engine, {\n * beforeRequest: async (request) => {\n * if (!isAuthorized(request)) {\n * return new Response('Unauthorized', { status: 401 });\n * }\n * // returning nothing lets the request proceed as normal\n * },\n * });\n * ```\n */\nexport function createAiHandler(engine: KubuildAiEngine, options?: CreateAiHandlerOptions) {\n return async (request: Request): Promise<Response> => {\n try {\n if (options?.beforeRequest) {\n const hookResult = await options.beforeRequest(request);\n if (hookResult instanceof Response) {\n return hookResult;\n }\n }\n\n if (request.method !== 'POST') {\n return new Response(\n JSON.stringify({\n success: false,\n error: {\n code: 'METHOD_NOT_ALLOWED',\n message: 'Only POST requests are accepted',\n },\n }),\n {\n status: 405,\n headers: {\n 'Content-Type': 'application/json',\n Allow: 'POST',\n },\n },\n );\n }\n\n const body = (await request.json().catch(() => null)) as AiApiRequestBody | null;\n\n // Handle opt-in SSE Streaming\n if (body && typeof body === 'object' && body.stream === true) {\n const mode = body.mode || 'full-page';\n\n // Token-level chat streaming (STORA-515) — routed separately from full-page\n // streaming below since it needs `messages`, not `prompt`.\n if (mode === 'chat') {\n if (!body.messages || !Array.isArray(body.messages) || body.messages.length === 0) {\n return new Response(\n JSON.stringify({\n success: false,\n error: {\n code: 'INVALID_CHAT_PARAMS',\n message: '\"messages\" array is required and must not be empty for chat mode',\n },\n }),\n {\n status: 400,\n headers: { 'Content-Type': 'application/json' },\n },\n );\n }\n\n const encoder = new TextEncoder();\n const readable = new ReadableStream({\n async start(controller) {\n try {\n for await (const event of engine.chatStream(\n {\n messages: body.messages!,\n currentDocument: body.currentDocument,\n selectedNodeId: body.selectedNodeId,\n },\n { signal: request.signal },\n )) {\n controller.enqueue(\n encoder.encode(`event: ${event.type}\\ndata: ${JSON.stringify(event)}\\n\\n`),\n );\n }\n } catch (err: unknown) {\n const message = err instanceof Error ? err.message : String(err);\n controller.enqueue(\n encoder.encode(\n `event: error\\ndata: ${JSON.stringify({ type: 'error', error: { code: 'CHAT_STREAM_ERROR', message } })}\\n\\n`,\n ),\n );\n } finally {\n controller.close();\n }\n },\n });\n\n return new Response(readable, {\n status: 200,\n headers: {\n 'Content-Type': 'text/event-stream',\n 'Cache-Control': 'no-cache, no-transform',\n Connection: 'keep-alive',\n },\n });\n }\n\n if (!body.prompt || typeof body.prompt !== 'string') {\n return new Response(\n JSON.stringify({\n success: false,\n error: {\n code: 'INVALID_PROMPT',\n message: '\"prompt\" is required for streaming generation',\n },\n }),\n {\n status: 400,\n headers: { 'Content-Type': 'application/json' },\n },\n );\n }\n\n const encoder = new TextEncoder();\n const readable = new ReadableStream({\n async start(controller) {\n try {\n for await (const event of engine.streamPage(\n {\n prompt: body.prompt!,\n stylePreference: body.stylePreference,\n tone: body.tone,\n locale: body.locale,\n metadata: body.metadata,\n },\n { signal: request.signal },\n )) {\n controller.enqueue(\n encoder.encode(`event: ${event.type}\\ndata: ${JSON.stringify(event)}\\n\\n`),\n );\n }\n } catch (err: unknown) {\n const message = err instanceof Error ? err.message : String(err);\n controller.enqueue(\n encoder.encode(\n `event: error\\ndata: ${JSON.stringify({ type: 'error', error: { code: 'STREAM_ERROR', message } })}\\n\\n`,\n ),\n );\n } finally {\n controller.close();\n }\n },\n });\n\n return new Response(readable, {\n status: 200,\n headers: {\n 'Content-Type': 'text/event-stream',\n 'Cache-Control': 'no-cache, no-transform',\n Connection: 'keep-alive',\n },\n });\n }\n\n // Default: Standard non-streaming JSON response (Backward-compatible)\n const { status, response } = await processAiRequest(\n engine,\n body,\n request.signal,\n );\n\n return new Response(JSON.stringify(response), {\n status,\n headers: {\n 'Content-Type': 'application/json',\n },\n });\n } catch (err: unknown) {\n const message = err instanceof Error ? err.message : String(err);\n return new Response(\n JSON.stringify({\n success: false,\n error: {\n code: 'INTERNAL_SERVER_ERROR',\n message,\n },\n }),\n {\n status: 500,\n headers: {\n 'Content-Type': 'application/json',\n },\n },\n );\n }\n };\n}\n"],"mappings":"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","names":["encoder","readable"]}
@@ -0,0 +1,184 @@
1
+ import type { Node, PageDocument, DocumentMetadata } from '@kubuild/schema';
2
+ import type { DocumentSecurityLimits } from '@kubuild/core';
3
+ export type AiGenerationMode = 'full-page' | 'section' | 'refactor' | 'chat';
4
+ export interface AiChatMessage {
5
+ role: 'user' | 'assistant' | 'system';
6
+ content: string;
7
+ timestamp?: number;
8
+ }
9
+ export interface AiChatRequest {
10
+ messages: AiChatMessage[];
11
+ currentDocument?: PageDocument;
12
+ selectedNodeId?: string;
13
+ systemPrompt?: string;
14
+ }
15
+ export interface AiChatResponse {
16
+ message: AiChatMessage;
17
+ }
18
+ export interface AiGeneratePageRequest {
19
+ prompt: string;
20
+ stylePreference?: string;
21
+ tone?: string;
22
+ locale?: string;
23
+ metadata?: Partial<DocumentMetadata>;
24
+ stream?: boolean;
25
+ }
26
+ export interface AiGenerateSectionRequest {
27
+ prompt: string;
28
+ stylePreference?: string;
29
+ targetSectionType?: string;
30
+ parentContext?: string;
31
+ }
32
+ export interface AiRefactorNodeRequest {
33
+ node: Node;
34
+ instruction: string;
35
+ stylePreference?: string;
36
+ }
37
+ export type AiStreamEvent = {
38
+ type: 'status';
39
+ message: string;
40
+ } | {
41
+ type: 'metadata';
42
+ metadata: DocumentMetadata;
43
+ rootPageNode: Node;
44
+ } | {
45
+ type: 'section';
46
+ index: number;
47
+ total: number;
48
+ section: Node;
49
+ } | {
50
+ type: 'complete';
51
+ document: PageDocument;
52
+ }
53
+ /**
54
+ * Token-level chat streaming (STORA-515). `delta` is the newly-arrived text fragment,
55
+ * `content` is the full accumulated assistant message so far — consumers that only
56
+ * care about the running text (e.g. rendering a live-updating bubble) can just use
57
+ * `content` and ignore `delta`.
58
+ */
59
+ | {
60
+ type: 'chat-chunk';
61
+ delta: string;
62
+ content: string;
63
+ }
64
+ /** Terminal event for a chat stream — mirrors `complete` for `streamPage`. */
65
+ | {
66
+ type: 'chat-complete';
67
+ message: AiChatMessage;
68
+ } | {
69
+ type: 'error';
70
+ error: {
71
+ code: string;
72
+ message: string;
73
+ };
74
+ };
75
+ export interface AiStreamCallbacks {
76
+ onStatus?: (message: string) => void;
77
+ onMetadata?: (metadata: DocumentMetadata, rootPage: Node) => void;
78
+ onSection?: (section: Node, index: number, total: number) => void;
79
+ onComplete?: (document: PageDocument) => void;
80
+ /** Fired for every partial chunk of a streaming chat response (STORA-515/516). */
81
+ onChatChunk?: (delta: string, content: string) => void;
82
+ /** Fired once, when a streaming chat response has finished assembling. */
83
+ onChatComplete?: (message: AiChatMessage) => void;
84
+ onError?: (error: Error) => void;
85
+ }
86
+ export interface AiErrorDetail {
87
+ code: string;
88
+ message: string;
89
+ details?: unknown;
90
+ }
91
+ export interface AiGenerateResponse<T = PageDocument | Node> {
92
+ success: boolean;
93
+ data?: T;
94
+ error?: AiErrorDetail;
95
+ rawModelResponse?: string;
96
+ usage?: {
97
+ promptTokens?: number;
98
+ completionTokens?: number;
99
+ };
100
+ }
101
+ export interface AiCompiledComponentProp {
102
+ name: string;
103
+ type: string;
104
+ defaultValue?: unknown;
105
+ options?: unknown[];
106
+ description?: string;
107
+ }
108
+ export interface AiCompiledComponentSpec {
109
+ type: string;
110
+ label: string;
111
+ category: string;
112
+ description?: string;
113
+ acceptsChildren: boolean;
114
+ allowedChildren?: string[];
115
+ disallowedParents?: string[];
116
+ defaultProps?: Record<string, unknown>;
117
+ props?: AiCompiledComponentProp[];
118
+ }
119
+ export interface AiProviderGenerateParams {
120
+ systemPrompt: string;
121
+ userPrompt: string;
122
+ messages?: AiChatMessage[];
123
+ jsonSchema?: Record<string, unknown>;
124
+ signal?: AbortSignal;
125
+ }
126
+ export interface AiProviderGenerateResult {
127
+ text: string;
128
+ usage?: {
129
+ promptTokens?: number;
130
+ completionTokens?: number;
131
+ };
132
+ }
133
+ export interface AiProviderAdapter {
134
+ readonly name: string;
135
+ generate(params: AiProviderGenerateParams): Promise<AiProviderGenerateResult>;
136
+ /**
137
+ * Optional token-level streaming variant (STORA-515). Adapters whose provider API
138
+ * supports incremental streaming (OpenAI, Anthropic, Gemini) should implement this as
139
+ * an async generator that `yield`s each text delta as it arrives over the wire, and
140
+ * `return`s the final `AiProviderGenerateResult` (full text + usage, mirroring
141
+ * `generate`) once the stream ends.
142
+ *
143
+ * Adapters that omit this are treated by `KubuildAiEngine` as non-streaming-capable:
144
+ * the engine falls back to a single `generate()` call and emits the whole response as
145
+ * one chunk through the same streaming interface, so callers never need to branch on
146
+ * adapter capability themselves.
147
+ */
148
+ generateStream?(params: AiProviderGenerateParams): AsyncGenerator<string, AiProviderGenerateResult, void>;
149
+ }
150
+ export interface ComponentDefinitionLike {
151
+ type: string;
152
+ label?: string;
153
+ category?: string;
154
+ description?: string;
155
+ acceptsChildren?: boolean;
156
+ allowedChildren?: string[];
157
+ disallowedParents?: string[];
158
+ defaultProps?: Record<string, unknown>;
159
+ propFields?: Array<{
160
+ name: string;
161
+ label?: string;
162
+ type?: string;
163
+ defaultValue?: unknown;
164
+ options?: Array<{
165
+ label: string;
166
+ value: unknown;
167
+ }>;
168
+ description?: string;
169
+ }>;
170
+ }
171
+ export interface ComponentRegistryLike {
172
+ list(): ComponentDefinitionLike[];
173
+ get?(type: string): ComponentDefinitionLike | undefined;
174
+ has?(type: string): boolean;
175
+ }
176
+ export interface KubuildAiEngineOptions {
177
+ registry?: ComponentRegistryLike;
178
+ adapter: AiProviderAdapter;
179
+ securityLimits?: DocumentSecurityLimits;
180
+ systemPromptPrefix?: string;
181
+ debug?: boolean;
182
+ logger?: (level: 'info' | 'warn' | 'error' | 'debug', message: string, meta?: unknown) => void;
183
+ }
184
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
package/package.json ADDED
@@ -0,0 +1,94 @@
1
+ {
2
+ "name": "@kubuild/ai",
3
+ "version": "0.3.0",
4
+ "description": "Component-aware AI generation engine and adapters for KUBUILD",
5
+ "type": "module",
6
+ "main": "./dist/index.cjs",
7
+ "module": "./dist/index.js",
8
+ "types": "./dist/index.d.ts",
9
+ "exports": {
10
+ ".": {
11
+ "types": "./dist/index.d.ts",
12
+ "import": "./dist/index.js",
13
+ "require": "./dist/index.cjs"
14
+ },
15
+ "./server": {
16
+ "types": "./dist/server/index.d.ts",
17
+ "import": "./dist/server/index.js",
18
+ "require": "./dist/server/index.cjs"
19
+ },
20
+ "./client": {
21
+ "types": "./dist/client/index.d.ts",
22
+ "import": "./dist/client/index.js",
23
+ "require": "./dist/client/index.cjs"
24
+ },
25
+ "./react": {
26
+ "types": "./dist/react/index.d.ts",
27
+ "import": "./dist/react/index.js",
28
+ "require": "./dist/react/index.cjs"
29
+ },
30
+ "./adapters": {
31
+ "types": "./dist/server/adapters/index.d.ts",
32
+ "import": "./dist/server/adapters/index.js",
33
+ "require": "./dist/server/adapters/index.cjs"
34
+ }
35
+ },
36
+ "files": [
37
+ "dist"
38
+ ],
39
+ "sideEffects": false,
40
+ "publishConfig": {
41
+ "access": "public"
42
+ },
43
+ "repository": {
44
+ "type": "git",
45
+ "url": "git+https://github.com/kustora/kubuild.git",
46
+ "directory": "packages/ai"
47
+ },
48
+ "keywords": [
49
+ "page-builder",
50
+ "ai-generation",
51
+ "website-builder",
52
+ "stora",
53
+ "kubuild",
54
+ "llm",
55
+ "gemini",
56
+ "openai"
57
+ ],
58
+ "author": "KUBUILD",
59
+ "license": "MIT",
60
+ "dependencies": {
61
+ "@kubuild/core": "0.3.0",
62
+ "@kubuild/schema": "0.3.0"
63
+ },
64
+ "peerDependencies": {
65
+ "react": "^18.0.0 || ^19.0.0",
66
+ "@kubuild/components": "0.3.0"
67
+ },
68
+ "peerDependenciesMeta": {
69
+ "@kubuild/components": {
70
+ "optional": true
71
+ },
72
+ "react": {
73
+ "optional": true
74
+ }
75
+ },
76
+ "devDependencies": {
77
+ "@types/node": "^26.2.0",
78
+ "@types/react": "^19.2.18",
79
+ "@types/react-test-renderer": "^18.3.0",
80
+ "react": "^19.2.8",
81
+ "react-test-renderer": "^19.2.0",
82
+ "tsup": "^8.3.6",
83
+ "typescript": "^6.0.0",
84
+ "vitest": "^3.0.5",
85
+ "@kubuild/components": "0.3.0"
86
+ },
87
+ "scripts": {
88
+ "build": "tsup && tsc --emitDeclarationOnly",
89
+ "dev": "tsup --watch",
90
+ "typecheck": "tsc --noEmit",
91
+ "lint": "eslint src",
92
+ "test": "vitest run"
93
+ }
94
+ }