npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@ybouhjira/hyperkit-ai-renderer

v0.1.0

Published

Transform raw data/intent into validated SolidKit UI schemas via LLM

Readme

@ybouhjira/hyperkit-ai-renderer

Transforms raw data and intent strings into validated HyperKit UI schemas using a cheap LLM (Haiku or Gemini Flash by default).

The Problem It Solves

When a smart model like Opus generates a response, it knows what information to present but should not be burdened with memorizing 18 content type schemas, their exact JSON shapes, and the selection rules for when each is appropriate. Making the main model output UI schemas directly is wasteful and error-prone.

This package implements the 2-LLM architecture:

Smart model (Opus)          Renderer model (Haiku)
─────────────────           ──────────────────────
"Here are the metrics:  →   [Receives catalog of 18
 CPU 80%, RAM 60%..."        content types + intent]
                          →   Outputs validated JSON array
                          →   Schema-validated by Effect

The renderer step is cheap, focused, and runs with a compressed system prompt (CONTENT_TYPE_CATALOG) that gives it everything it needs. The main model stays context-clean.

Architecture

renderData(intent, options?)
  │
  ├── rendererStep(options)         ← creates a Step<string, SectionContent[]>
  │     ├── systemPrompt = CONTENT_TYPE_CATALOG + additionalContext?
  │     ├── model = "haiku" (default)
  │     ├── parseResponse = extractJson()   ← strips markdown fences
  │     └── outputSchema = S.Array(SectionContent)  ← Effect Schema validation
  │
  └── Pipeline.run(pipeline, intent)
        └── Returns { content: SectionContent[], trace: PipelineTrace }

LlmProvider is injected via Effect's dependency injection — the renderer itself has no direct dependency on any specific LLM SDK.

Installation

npm install @ybouhjira/hyperkit-ai-renderer

Peer dependencies:

npm install effect @ybouhjira/hyperkit-llm-pipeline @ybouhjira/hyperkit-mcp

Quick Start

import { Effect } from 'effect';
import { renderData } from '@ybouhjira/hyperkit-ai-renderer';
import { CliProvider } from '@ybouhjira/hyperkit-llm-pipeline';

const program = renderData('Show a summary of these server metrics: CPU 80%, Memory 60%, Disk 45%');

const { content, trace } = await Effect.runPromise(program.pipe(Effect.provide(CliProvider())));

console.log(content);
// [{ type: 'summary-grid', items: [{ icon: '💻', title: 'CPU', ... }] }]

console.log(`Rendered in ${trace.totalDurationMs}ms, cost $${trace.totalCostUsd.toFixed(5)}`);

How the Catalog Works

CONTENT_TYPE_CATALOG is a compressed system prompt embedded in this package. It is sent to the renderer LLM on every call and contains:

  • 18 content type definitions with their exact JSON schemas and examples
  • A RULES section requiring JSON-only output (no markdown, no explanation)
  • A SELECTION GUIDE mapping common data patterns to appropriate content types

The catalog is compact by design — it fits comfortably in Haiku's context window with room for the intent and any additional context you provide.

import { CONTENT_TYPE_CATALOG } from '@ybouhjira/hyperkit-ai-renderer';

// Inspect what the renderer LLM receives as its system prompt
console.log(CONTENT_TYPE_CATALOG);

The 18 Content Types

| Type | Use For | | --------------- | -------------------------------------------- | | summary-grid | Key metrics, KPI cards with icons | | table | Structured tabular data | | code | Code snippets with syntax highlighting | | flow-diagram | Architecture layers | | layer-stack | Labeled layer visualization | | gap-analysis | Issues with critical/important/nice severity | | timeline | Step-by-step progress with status | | package-tree | Package/module overviews | | preset-grid | Option cards with gradients | | source-list | Grouped reference links | | text | Rich or plain text blocks | | issue-list | Bug/issue cards with icons | | decision-grid | Interactive option selection | | poll | Interactive quick vote | | form-fields | Interactive form inputs | | mockup-layout | Template-based UI mockups | | mockup-tree | Free-form component trees | | app | Live SolidJS applications |

API Reference

renderData(intent, options?)

Main entry point. Returns an Effect requiring LlmProvider in context.

function renderData(
  intent: string,
  options?: RenderDataOptions
): Effect.Effect<RenderResult, LlmError, LlmProvider>;

Parameters:

  • intent — the raw data or description of what to render
  • options.model — LLM model alias (default: "haiku")
  • options.additionalContext — extra instructions appended to the catalog system prompt
  • options.maxAttempts — retry budget for malformed JSON responses (default: 2)

Returns:

interface RenderResult {
  readonly content: readonly SectionContent[]; // validated UI blocks
  readonly trace: PipelineTrace; // timing, tokens, cost, attempts
}

rendererStep(options?)

Creates a Step<string, SectionContent[]> for use in a custom pipeline. Use this when you need to compose the renderer with other steps.

function rendererStep(options?: RendererStepOptions): Step<string, readonly SectionContent[]>;
import { rendererStep } from '@ybouhjira/hyperkit-ai-renderer';
import { Pipeline } from '@ybouhjira/hyperkit-llm-pipeline';

const step = rendererStep({ model: 'gemini-flash', additionalContext: 'Focus on security.' });
const pipeline = Pipeline.from('my-pipeline', step);

extractJson(response)

Strips markdown code fences from an LLM response and parses JSON. Used internally by rendererStep but exported for use in custom steps.

function extractJson(response: string): unknown;

Handles:

  • Raw JSON strings
  • ```json ... ``` code blocks
  • ``` ... ``` blocks without a language tag

Throws SyntaxError on malformed JSON.


CONTENT_TYPE_CATALOG

The system prompt string given to the renderer LLM. Export it directly if you need to inspect or extend it.

const CONTENT_TYPE_CATALOG: string;

Custom Model and Provider

Override the model per call:

const { content } = await Effect.runPromise(
  renderData('intent', { model: 'gemini-flash' }).pipe(Effect.provide(GeminiProvider()))
);

Add domain-specific instructions:

const { content } = await Effect.runPromise(
  renderData('AWS cost report for Q1', {
    additionalContext: 'Prefer table and summary-grid. Use USD for all cost values.',
  }).pipe(Effect.provide(CliProvider()))
);

Testing with MockProvider

MockProvider from @ybouhjira/hyperkit-llm-pipeline intercepts LLM calls without hitting any real API. Pass a fixed response string keyed by model name, or a function that receives the full LlmRequest.

import { Effect } from 'effect';
import { MockProvider } from '@ybouhjira/hyperkit-llm-pipeline';
import { renderData } from '@ybouhjira/hyperkit-ai-renderer';

it('renders a summary-grid from metrics', async () => {
  const mockResponse = JSON.stringify([
    {
      type: 'summary-grid',
      items: [{ icon: '💻', title: 'CPU', description: '80% usage', iconColor: 'teal' }],
    },
  ]);

  const program = renderData('CPU usage is 80%').pipe(
    Effect.provide(MockProvider({ haiku: mockResponse }))
  );

  const { content } = await Effect.runPromise(program);
  expect(content[0].type).toBe('summary-grid');
});

Inspect the actual request sent to the LLM:

import type { LlmRequest } from '@ybouhjira/hyperkit-llm-pipeline';

it('includes the intent in the user prompt', async () => {
  const captured: LlmRequest[] = [];

  const program = renderData('show disk usage').pipe(
    Effect.provide(
      MockProvider((req: LlmRequest) => {
        captured.push(req);
        return mockResponse;
      })
    )
  );

  await Effect.runPromise(program);
  expect(captured[0].userPrompt).toContain('show disk usage');
  expect(captured[0].systemPrompt).toContain('summary-grid');
});

Test retry behavior:

it('succeeds on retry after first attempt fails', async () => {
  let calls = 0;

  const program = renderData('metrics', { maxAttempts: 2 }).pipe(
    Effect.provide(
      MockProvider(() => {
        calls++;
        return calls === 1 ? 'bad json {{{' : validResponse;
      })
    )
  );

  const { trace } = await Effect.runPromise(program);
  expect(trace.steps[0].attempts).toBe(2);
});

Dependencies

| Package | Role | | ---------------------------------- | ------------------------------------------------------------------ | | @ybouhjira/hyperkit-llm-pipeline | Step, Pipeline, LlmProvider, PipelineTrace, MockProvider | | @ybouhjira/hyperkit-mcp | SectionContent Effect Schema (the 18 UI content types) | | effect (peer) | Schema validation, dependency injection, Effect.Effect type |