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

@geenius/ai

v0.17.0

Published

Geenius AI — Reusable AI packages for Convex apps (React + SolidJS)

Readme

@geenius/ai

Reusable AI contracts, provider adapters, framework bindings, and launch persistence providers for Geenius apps.

@geenius/ai is the free FSL lite package for low-level runtime and UI integration. The commercial siblings are @geenius/ai-magic for high-level AI Magic wizard surfaces and @geenius/ai-workflow for hosted workflow orchestration.

Install

pnpm add @geenius/ai

Import Surface

import { DEFAULT_MODELS, DEFAULT_PROVIDERS, defineAIConfig } from '@geenius/ai'
import { DEFAULT_VOICES, buildSkillPrompt, createSkillRegistry } from '@geenius/ai'
import { ChatPage, GenerationCard, ModelTestRunner, useAI } from '@geenius/ai/react'
import { ChatPage as ChatPageCss, GenerationCard as GenerationCardCss } from '@geenius/ai/react-css'
import { ChatPage as SolidChatPage, GenerationCard as SolidGenerationCard, createAI } from '@geenius/ai/solidjs'
import { ChatPage as SolidChatPageCss, GenerationCard as SolidGenerationCardCss } from '@geenius/ai/solidjs-css'
import { ChatPage as ChatPageNative, ModelSelector as ModelSelectorNative } from '@geenius/ai/react-native'
import { aiTables, generateTextArgs, performAICall } from '@geenius/ai/convex'
import { createNeonAIStore, runAIMigrations } from '@geenius/ai/neon'
import { createCloudflareKVAIStore, createMemoryKVNamespace } from '@geenius/ai/cloudflareKV'
import { createMemoryAIStore } from '@geenius/ai/memory'

@geenius/ai resolves to the shared framework-agnostic contract. Framework-specific code is exported only from the framework subpaths.

Quick Start

Shared configuration

import { defineAIConfig } from '@geenius/ai'

export const aiConfig = defineAIConfig({
  defaultProvider: 'openai',
  defaultModel: 'gpt-4o-mini',
  providers: [
    {
      type: 'openai',
      name: 'OpenAI',
      baseUrl: 'https://api.openai.com/v1',
      apiKeyEnvVar: 'OPENAI_API_KEY',
      isActive: true,
      models: ['gpt-4o-mini'],
    },
  ],
})

React usage

import { ChatPage } from '@geenius/ai/react'

export function SupportAssistant() {
  return (
    <ChatPage
      model="gpt-4o-mini"
      systemPrompt="You are a concise support copilot."
      callGenerateText={async ({ model, messages }) => {
        return {
          content: `Generated ${messages.length} message(s) with ${model}.`,
          model,
          provider: 'openai',
          type: 'text',
          durationMs: 42,
          finishReason: 'stop',
        }
      }}
    />
  )
}

React CSS usage

import { AILogsPage, ChatPage, ModelTestPage, useChat } from '@geenius/ai/react-css'
import '@geenius/ai/react-css/styles.css'

export function EmbeddedAssistant() {
  const callGenerateText = async ({ model, messages }) => ({
    content: `Generated ${messages.length} message(s) with ${model}.`,
    model,
    provider: 'openai',
    type: 'text',
    durationMs: 42,
    finishReason: 'stop',
  })
  const chat = useChat({
    model: 'gpt-4o-mini',
    callGenerateText,
  })

  return (
    <>
      <button type="button" onClick={() => void chat.sendMessage('Summarize today')}>
        Send sample prompt
      </button>
      <ChatPage model="gpt-4o-mini" callGenerateText={callGenerateText} />
      <AILogsPage callListLogs={async () => []} />
      <ModelTestPage availableModels={['gpt-4o-mini']} />
    </>
  )
}

SolidJS usage

import { createAI } from '@geenius/ai/solidjs'

const ai = createAI({
  callGenerateText: async ({ model, messages }) => {
    return {
      content: `Generated ${messages.length} message(s) with ${model}.`,
      model,
      provider: 'openai',
      type: 'text',
      durationMs: 42,
      finishReason: 'stop',
    }
  },
})

The @geenius/ai/react, @geenius/ai/react-css, @geenius/ai/solidjs, @geenius/ai/solidjs-css, and @geenius/ai/react-native entrypoints all use the same portable call* callback contract so UI variants can stay backend-agnostic.

React Native usage

import { AIProvider, ChatPage } from '@geenius/ai/react-native'

export function App() {
  return (
    <AIProvider
      defaults={{
        ai: {
          callGenerateText: async ({ model, messages }) => ({
            content: `Generated ${messages.length} message(s) with ${model}.`,
            model,
            provider: 'openai',
            type: 'text',
            durationMs: 42,
            finishReason: 'stop',
          }),
        },
      }}
    >
      <ChatPage />
    </AIProvider>
  )
}

Convex usage

import { defineSchema } from 'convex/server'
import { aiTables } from '@geenius/ai/convex'

export default defineSchema({
  ...aiTables,
})

Neon usage

import { createNeonAIStore, runAIMigrations } from '@geenius/ai/neon'

const store = createNeonAIStore({ execute: sql })
await runAIMigrations(sql)
const conversation = await store.createConversation({
  userId: 'user_1',
  title: 'Support assistant',
  model: 'gpt-4o-mini',
})
await store.addMessage({
  conversationId: conversation.id,
  userId: 'user_1',
  role: 'user',
  content: 'Summarize today',
})
await store.saveLog({
  requestId: 'req_1',
  model: 'gpt-4o-mini',
  provider: 'openai',
  caller: 'support-assistant',
  type: 'text',
  timestamp: Date.now(),
  durationMs: 42,
  systemPrompt: '',
  userPrompt: 'Summarize today',
  hasImage: false,
  requestBodySize: 128,
  status: 'success',
  httpStatus: 200,
  responseContent: 'Summary generated.',
  responseSize: 18,
})

Cloudflare KV usage

import { createCloudflareKVAIStore, createMemoryKVNamespace } from '@geenius/ai/cloudflareKV'

const namespace = createMemoryKVNamespace()
const store = createCloudflareKVAIStore({ namespace, keyPrefix: 'ai', ttlSeconds: 3600 })

type CachedCompletion = {
  content: string
  model: string
}

await store.putCache<CachedCompletion>(
  'prompt:launch-recap',
  { content: 'Launch recap generated.', model: 'gpt-4o-mini' },
  { scope: 'user_1', ttlSeconds: 300 },
)
const cachedCompletion = await store.getCache<CachedCompletion>('prompt:launch-recap', {
  scope: 'user_1',
})

await store.putSession(
  'session_realtime_1',
  { conversationId: 'conv_1', status: 'streaming' },
  { ttlSeconds: 900 },
)
const realtimeSession = await store.getSession<{
  conversationId: string
  status: string
}>('session_realtime_1')

await store.putRateLimit(
  'user_1:gpt-4o-mini',
  { count: 4, limit: 20, resetAt: Date.now() + 60_000 },
  { scope: 'provider:openai', ttlSeconds: 60 },
)
const rateLimit = await store.getRateLimit('user_1:gpt-4o-mini', {
  scope: 'provider:openai',
})

Cloudflare KV short-lived helpers share the store key prefix, accept an optional scope, and apply TTLs for cache, session, and rate-limit state. TTL values must satisfy Cloudflare KV's 60-second minimum.

Memory usage

import { createMemoryAIStore, createMemoryStore } from '@geenius/ai/memory'

let now = Date.UTC(2026, 0, 1)
const memory = createMemoryStore({
  maxPerNamespace: 2,
  autoExpireDays: 30,
  now: () => now,
})

await memory.set({
  namespace: 'user',
  scopeId: 'user_1',
  type: 'preference',
  importance: 'high',
  key: 'tone',
  value: 'concise and technical',
})
await memory.set({
  namespace: 'user',
  scopeId: 'user_1',
  type: 'preference',
  importance: 'medium',
  key: 'currency',
  value: 'EUR',
})

const tone = await memory.get('user', 'tone', 'user_1')
const matches = await memory.search({
  namespace: 'user',
  scopeId: 'user_1',
  query: 'technical',
  limit: 5,
})

now += 31 * 24 * 60 * 60 * 1000
const expiredTone = await memory.get('user', 'tone', 'user_1') // null after auto expiry

const store = createMemoryAIStore()
await store.saveLog({ model: 'gpt-4o-mini', provider: 'openai' })
await store.clear()

createMemoryStore() implements the shared MemoryStore contract for prompt memory. maxPerNamespace evicts the lowest-priority, least-recently-accessed entries when a namespace exceeds the configured limit; autoExpireDays assigns an expiry timestamp to entries that do not provide one.

API Reference

The complete architecture and launch criteria live in .docs/DOCS/PACKAGES/AI.md. The package README stays focused on the public import surface.

Root: @geenius/ai

The root entrypoint is framework-agnostic. It exports shared contracts and helpers only; there is no @geenius/ai/shared subpath.

| Area | Key exports | Use when | | --- | --- | --- | | Configuration | defineAIConfig, mergeAIConfig, findModelConfig, findProviderConfig, getModelsByCapability, getProviderForModel, DEFAULT_MODELS, DEFAULT_PROVIDERS, DEFAULT_VOICES | Building provider/model registries that UI and adapters can share. | | Generation | getAIGenerationContent, getAIImageAssetSource, getAIMediaAssetSource, isAIGenerationResponse, generateStructuredOutputWithValidation, parseAndValidateStructuredOutput, withStructuredOutputSchemaInstruction | Normalizing provider responses and validating structured output. | | Conversations | createAIConversation, listAIConversations, filterAIConversations, searchAIConversations, patchAIConversation, archiveAIConversation, renameAIConversation, setAIConversationFavorite, updateAIConversationTags, moveAIConversationToFolder, createDbAIConversationPersistence | Managing portable conversation state before it reaches a UI or DB adapter. | | Content | BUILT_IN_TEMPLATES, buildActionSystemPrompt, buildContentPrompt plus Content* types | Creating rewrite, summarize, translate, tone, and extraction prompts. | | Memory | DEFAULT_MEMORY_CONFIG, buildMemoryContext, extractPreferenceHints plus MemoryStore, MemoryEntry, and memory query types | Injecting user/org memory into prompts without coupling to a storage backend. | | Skills | BUILT_IN_SKILLS, buildSkillPrompt, createSkillRegistry plus Skill* types | Registering tool-like skills and building skill execution prompts. | | Providers and errors | createProvider, createAdapterAIProvider, generateTextWithRetries, resolveProviderForModel, clearProviderCache, AIError, AIConfigurationError, AIProviderRequestError, AIProviderTimeoutError, AIStateError, AIUnsupportedOperationError, toAIError, requireAIValue | Bridging provider adapters and surfacing normalized errors. | | Shared types | AIMessage, AIChatMessage, AIConversation, AILogEntry, AIModel, AIProviderConfig, AIGenerationResult, AITranscriptionResult, AIVoiceOption, ChatWindowProps, ImageGeneratorProps, VoiceSelectorProps, and related option/result types | Typing callbacks, UI props, adapter payloads, and persistence records across variants. |

UI Variants

All UI variants consume the same portable call* callback contract and keep persistence outside the component layer.

| Subpath | Key exports | Notes | | --- | --- | --- | | @geenius/ai/react | AIProvider, useAIProviderContext, useAI, useChat, useAILogs, useAIModels, useContentManager, useImageGeneration, useMemory, useModelTest, useRealtimeAudio, useSkills, useTextToSpeech, useTranscription, useVideoGeneration, ModelSelector, VoiceSelector, AILogTable, ChatWindow, GenerationCard, ImageGenerator, ModelTestRunner, AILogsPage, ChatPage, ModelTestPage | React + Tailwind 4 utility classes. | | @geenius/ai/react-css | Same provider, hook, component, and page surface as React | React + Vanilla CSS BEM classes. Import @geenius/ai/react-css/styles.css. | | @geenius/ai/solidjs | AIProvider, useAIProviderContext, createAI, createChat, createAILogs, createAIModels, createContentManager, createImageGeneration, createMemory, createModelTest, createRealtimeAudio, createSkills, createTextToSpeech, createTranscription, createVideoGeneration, matching components, and pages | SolidJS + Tailwind 4 utility classes. | | @geenius/ai/solidjs-css | Same SolidJS provider, primitive, component, and page surface as SolidJS | SolidJS + Vanilla CSS BEM classes. Import @geenius/ai/solidjs-css/styles.css. | | @geenius/ai/react-native | AIProvider, useAIProviderContext, native hooks, nativeTokens, FlatList, Pressable, ScrollView, StyleSheet, Text, TextInput, View, native components, and native pages | React Native StyleSheet primitives backed by shared tokens. |

Persistence Providers

These subpaths are launch DB/storage adapters. UI variants do not import them directly; app code passes callbacks or store methods into UI hooks and pages.

| Subpath | Key exports | Use when | | --- | --- | --- | | @geenius/ai/convex | aiTables, generateTextArgs, performAICall, createLogEntry, validators and query/mutation helpers | Wiring Convex schema, queries, mutations, and action arguments for AI logs and calls. | | @geenius/ai/neon | createNeonAIStore, runAIMigrations, aiMigrations, createNeonAIRlsPolicyStatements, createNeonAITenantContextStatement, Neon store/input/filter types | Storing logs, conversations, messages, model costs, providers, and tenant-aware policy metadata in native Neon SQL. | | @geenius/ai/cloudflareKV | createCloudflareKVAIStore, createMemoryKVNamespace, buildCloudflareKVAIKey, createCloudflareKVAIKeys, CLOUDFLARE_KV_AI_CAPABILITIES, KV option/store types | Running edge-friendly key/value storage with TTL-backed cache, session, and rate-limit helpers. | | @geenius/ai/memory | createMemoryAIStore, createMemoryStore, memory AI store/input/filter/snapshot types | Running deterministic in-process stores for tests, demos, Storybook fixtures, and local development. |

Stylesheet Subpaths

| Subpath | Exports | | --- | --- | | @geenius/ai/react-css/styles.css | The React Vanilla CSS stylesheet and its ambient CSS module typing. | | @geenius/ai/solidjs-css/styles.css | The SolidJS Vanilla CSS stylesheet and its ambient CSS module typing. |

Package Layout

  • @geenius/ai: provider configuration, model registry, typed errors, content helpers, skills, memory, and framework-agnostic runtime helpers.
  • @geenius/ai/react: headless React hooks, components, and page compositions.
  • @geenius/ai/react-css: React hooks and plain-CSS component/page surfaces.
  • @geenius/ai/solidjs: SolidJS primitives, components, and page compositions.
  • @geenius/ai/solidjs-css: SolidJS primitives and plain-CSS component/page surfaces.
  • @geenius/ai/react-native: React Native hooks, components, and page compositions for native AI surfaces.
  • @geenius/ai/convex: schema tables, argument validators, and backend helper exports.
  • @geenius/ai/neon: Postgres/Neon logs, conversations, messages, model costs, and append-only migration runner.
  • @geenius/ai/cloudflareKV: edge KV log, conversation, message, and model store.
  • @geenius/ai/memory: deterministic in-process store for tests, demos, and Storybook fixtures.

Storybook

Development-only review surfaces are stock Storybook v10 apps wired through @geenius/storybook. Each implemented UI variant has its own app so provider/theme/runtime differences are exercised independently.

Build them locally with:

pnpm --filter ./apps/storybook-react build
pnpm --filter ./apps/storybook-react-css build
pnpm --filter ./apps/storybook-solidjs build
pnpm --filter ./apps/storybook-solidjs-css build

Run them locally with:

pnpm --filter ./apps/storybook-react dev
pnpm --filter ./apps/storybook-react-css dev
pnpm --filter ./apps/storybook-solidjs dev
pnpm --filter ./apps/storybook-solidjs-css dev

Contributing tests

The test matrix is driven from variants.json. Add a variant or provider there first, then add the matching package directory, Storybook/review app, Playwright harness coverage, bundle budget, and coverage target. Scripts and configs read the manifest through @geenius/release-toolkit; do not hardcode variant lists in package.json, Playwright config, or smoke gates.

Useful gates:

  • pnpm test:gauntlet runs the PR-blocking lint, type, unit, packed-smoke, size, supply-chain, and license checks.
  • pnpm test:all runs the extended pre-release stack: gauntlet, DB conformance, migrations, Storybook, e2e, a11y, visual, perf, and coverage.
  • pnpm run test:a11y runs axe/keyboard/focus coverage across implemented web variants.
  • pnpm run test:visual runs default-on chromium visual regression; update local baselines with pnpm run test:visual -- --update-snapshots.
  • pnpm run test:storybook:build builds every implemented per-variant Storybook app.
  • pnpm run test:coverage aggregates Vitest coverage. Current legacy package-wide coverage is below the v1 target and must be raised before strict release gating.

License

FSL-1.1-Apache-2.0 for the free tier, with proprietary commercial licensing for paid Geenius distributions.