SDK Reference
Initialization

Initialization

Initialize the Grounded Intelligence SDK once at your application's entry point (e.g., main.ts, App.tsx, or _app.tsx).

Note: The package is installed as lumina-sdk, but we refer to it as the Grounded Intelligence SDK.

Basic Setup

import { Lumina, CaptureTranscript } from 'lumina-sdk'
 
Lumina.init({
  endpoint: 'https://your-ingest-server.com',
  writeKey: 'gi_xxxxx',
  captureTranscript: CaptureTranscript.Full,
  maskFn: (text) => text,
  enableToolWrapping: true,
  flushIntervalMs: 5000,
  maxBatchBytes: 100_000,
  uiAnalytics: createDummyProvider(),
})

Configuration Options

Required Options

OptionTypeDescription
writeKeystringAPI key from dashboard (gi_...)
endpointstringIngest server URL (your Grounded Intelligence backend)

Core Options

OptionTypeDescription
captureTranscriptCaptureTranscriptFull | Masked | None
maskFn(text: string) => stringPII masking function
enableToolWrappingbooleanEnable automatic tool call tracking
flushIntervalMsnumberBuffer flush interval (default: 5000ms)
maxBatchBytesnumberMax batch size before auto-flush (default: 100KB)
uiAnalyticsUIAnalyticsProviderUI provider (PostHog, etc.)
systemAnalyticsSystemAnalyticsProviderOptional: system tracing provider

Provider Configuration

PostHog (UI Analytics)

import { postHogProvider } from 'lumina-sdk/providers/posthog'
import posthog from 'posthog-js'
 
// Initialize PostHog
posthog.init('phc_xxxxx', {
  api_host: 'https://us.posthog.com',
  capture_pageview: true,
  session_recording: {
    recordCrossOriginIframes: true
  }
})
 
// Configure Lumina with PostHog
Lumina.init({
  // ... other options
  uiAnalytics: postHogProvider({
    apiKey: 'phc_xxxxx',
    host: 'https://us.posthog.com'
  })
})

Complete Provider Setup

import { Lumina, CaptureTranscript } from 'lumina-sdk'
import { postHogProvider } from 'lumina-sdk/providers/posthog'
import posthog from 'posthog-js'
 
// Initialize PostHog
posthog.init('phc_xxxxx', {
  api_host: 'https://us.posthog.com',
  capture_pageview: true,
  session_recording: { recordCrossOriginIframes: true }
})
 
// Initialize Lumina with both providers
Lumina.init({
  endpoint: 'https://your-ingest-server.com',
  writeKey: 'lum_pk_xxxxx',
  captureTranscript: CaptureTranscript.Masked,
  maskFn: (text) => text.replace(/[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,}/g, '<EMAIL>'),
  flushIntervalMs: 5000,
  maxBatchBytes: 100_000,
  uiAnalytics: postHogProvider({
    apiKey: 'phc_xxxxx',
    host: 'https://us.posthog.com',
    projectId: '12345' // Optional: for replay URL generation
  }),
})

Environment-Specific Configuration

Development

Lumina.init({
  endpoint: 'http://localhost:8080/v1/ingest',
  writeKey: 'dev_write_key',
  sourceId: 'webapp@dev',
  captureTranscript: CaptureTranscript.Full, // No masking in dev
  flushIntervalMs: 1000, // More frequent flushes for testing
  sampling: {
    turn: 1.0, // Capture everything in dev
    uiEvent: 1.0,
    span: 1.0
  }
})

Production

Lumina.init({
  endpoint: process.env.NEXT_PUBLIC_LUMINA_ENDPOINT!,
  writeKey: process.env.NEXT_PUBLIC_LUMINA_WRITE_KEY!,
  
  // Protect PII in production
  captureTranscript: CaptureTranscript.Masked,
  maskFn: (text) => text
    .replace(/[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,}/g, '<EMAIL>')
    .replace(/\d{4}-?\d{4}-?\d{4}-?\d{4}/g, '<CARD>')
    .replace(/\b\d{3}-\d{2}-\d{4}\b/g, '<SSN>'),
  
  // Optimize for high traffic
  flushIntervalMs: 5000,
  maxBatchBytes: 200_000,
  
  uiAnalytics: postHogProvider({
    apiKey: process.env.NEXT_PUBLIC_POSTHOG_KEY!,
    host: 'https://us.posthog.com'
  })
})

Staging

Lumina.init({
  endpoint: 'https://staging-ingest.yourdomain.com',
  writeKey: process.env.NEXT_PUBLIC_LUMINA_WRITE_KEY!,
  
  captureTranscript: CaptureTranscript.Masked,
  maskFn: (text) => text.replace(/[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,}/g, '<EMAIL>'),
  
  flushIntervalMs: 3000,
  maxBatchBytes: 150_000,
})

Framework-Specific Setup

Next.js (App Router)

// app/providers.tsx
'use client'
 
import { useEffect } from 'react'
import { Lumina, CaptureTranscript } from 'lumina-sdk'
import { postHogProvider } from 'lumina-sdk/providers/posthog'
import posthog from 'posthog-js'
 
export function Providers({ children }: { children: React.ReactNode }) {
  useEffect(() => {
    // Initialize PostHog
    posthog.init(process.env.NEXT_PUBLIC_POSTHOG_KEY!, {
      api_host: 'https://us.posthog.com',
      capture_pageview: true
    })
    
    // Initialize Lumina
    Lumina.init({
      endpoint: process.env.NEXT_PUBLIC_LUMINA_ENDPOINT!,
      writeKey: process.env.NEXT_PUBLIC_LUMINA_WRITE_KEY!,
      captureTranscript: CaptureTranscript.Masked,
      maskFn: (text) => text,
      uiAnalytics: postHogProvider({
        apiKey: process.env.NEXT_PUBLIC_POSTHOG_KEY!,
        host: 'https://us.posthog.com'
      })
    })
  }, [])
  
  return <>{children}</>
}
// app/layout.tsx
import { Providers } from './providers'
 
export default function RootLayout({ children }: { children: React.ReactNode }) {
  return (
    <html lang="en">
      <body>
        <Providers>{children}</Providers>
      </body>
    </html>
  )
}

Next.js (Pages Router)

// pages/_app.tsx
import { useEffect } from 'react'
import { Lumina, CaptureTranscript } from 'lumina-sdk'
import { postHogProvider } from 'lumina-sdk/providers/posthog'
import posthog from 'posthog-js'
import type { AppProps } from 'next/app'
 
export default function App({ Component, pageProps }: AppProps) {
  useEffect(() => {
    // Initialize PostHog
    posthog.init(process.env.NEXT_PUBLIC_POSTHOG_KEY!, {
      api_host: 'https://us.posthog.com'
    })
    
    // Initialize Lumina
Lumina.init({
  endpoint: process.env.NEXT_PUBLIC_LUMINA_ENDPOINT!,
  writeKey: process.env.NEXT_PUBLIC_LUMINA_WRITE_KEY!,
  captureTranscript: CaptureTranscript.Masked,
  maskFn: (text) => text,
  uiAnalytics: postHogProvider({
    apiKey: process.env.NEXT_PUBLIC_POSTHOG_KEY!,
    host: 'https://us.posthog.com'
  })
})
  }, [])
  
  return <Component {...pageProps} />
}

React (Create React App / Vite)

// src/main.tsx or src/index.tsx
import React from 'react'
import ReactDOM from 'react-dom/client'
import { Lumina, CaptureTranscript } from 'lumina-sdk'
import { postHogProvider } from 'lumina-sdk/providers/posthog'
import posthog from 'posthog-js'
import App from './App'
 
// Initialize PostHog
posthog.init(import.meta.env.VITE_POSTHOG_KEY, {
  api_host: 'https://us.posthog.com'
})
 
// Initialize Lumina
Lumina.init({
  endpoint: import.meta.env.VITE_LUMINA_ENDPOINT,
  writeKey: import.meta.env.VITE_LUMINA_WRITE_KEY,
  sourceId: 'webapp@prod',
  captureTranscript: CaptureTranscript.Full,
  uiAnalytics: postHogProvider({
    apiKey: import.meta.env.VITE_POSTHOG_KEY,
    host: 'https://us.posthog.com'
  })
})
 
ReactDOM.createRoot(document.getElementById('root')!).render(
  <React.StrictMode>
    <App />
  </React.StrictMode>
)

Best Practices

1. Initialize Once

Always initialize at the application entry point, never in individual components:

// ✅ Good: Initialize once at app startup
// main.ts or App.tsx
Lumina.init({ /* ... */ })
 
// ❌ Bad: Initialize in component
function ChatComponent() {
  Lumina.init({ /* ... */ }) // Don't do this!
}

2. Use Environment Variables

Store sensitive keys in environment variables:

# .env.local
NEXT_PUBLIC_LUMINA_ENDPOINT=https://ingest.yourdomain.com
NEXT_PUBLIC_LUMINA_WRITE_KEY=lum_pk_xxxxx
NEXT_PUBLIC_POSTHOG_KEY=phc_xxxxx
LANGFUSE_PUBLIC_KEY=pk-lf-xxxxx
LANGFUSE_SECRET_KEY=sk-lf-xxxxx

3. Configure for Environment

Use different settings for dev/staging/prod:

const isDev = process.env.NODE_ENV === 'development'
 
Lumina.init({
  endpoint: isDev ? 'http://localhost:8080' : process.env.NEXT_PUBLIC_LUMINA_ENDPOINT!,
  writeKey: process.env.NEXT_PUBLIC_LUMINA_WRITE_KEY!,
  captureTranscript: isDev ? CaptureTranscript.Full : CaptureTranscript.Masked,
})

4. Monitor Initialization

Verify initialization succeeded:

Lumina.init({ /* ... */ })
 
console.log('Lumina initialized:', Lumina.getDistinctId())

Troubleshooting

SDK Not Initializing

Problem: Events not being sent

Solution: Ensure init() is called before any event capture:

// ✅ Correct order
Lumina.init({ /* ... */ })
const session = await Lumina.session.start()
 
// ❌ Wrong order
const session = await Lumina.session.start()
Lumina.init({ /* ... */ }) // Too late!

Provider Errors

Problem: Provider initialization failures

Solution: Check that peer dependencies are installed:

npm install posthog-js

TypeScript Errors

Problem: Type errors with providers

Solution: Ensure correct imports:

import { postHogProvider } from 'lumina-sdk/providers/posthog'

Next Steps