npm.io
5.8.0 • Published yesterday

@runtypelabs/sdk

Licence
MIT
Version
5.8.0
Deps
0
Size
4.5 MB
Vulns
0
Weekly
0

@runtypelabs/sdk

TypeScript client SDK for the Runtype API with FlowBuilder for constructing and executing AI workflows.

Official npm package for the Runtype AI platform

Installation

npm install @runtypelabs/sdk
# or
yarn add @runtypelabs/sdk
# or
pnpm add @runtypelabs/sdk

Quick Start

import { RuntypeClient } from '@runtypelabs/sdk'

// Initialize the client
const runtype = new RuntypeClient({
  apiKey: 'your-api-key',
  baseUrl: 'https://api.runtype.com', // optional, defaults to production
})

// Use the FlowBuilder for intuitive flow construction
const result = await runtype
  .flow('My AI Workflow')
  .withRecord({ name: 'Test', type: 'data', metadata: { url: 'https://example.com' } })
  .fetchUrl({
    name: 'Fetch Content',
    url: '{{_record.metadata.url}}',
    outputVariable: 'content',
  })
  .prompt({
    name: 'Analyze',
    model: 'gpt-4',
    userPrompt: 'Analyze this content: {{content}}',
    responseFormat: 'json',
  })
  .run({ streamResponse: true, flowMode: 'virtual' })

// Get the analysis result
const analysis = await result.getResult('Analyze')
console.log(analysis)

Features

  • FlowBuilder API: Fluent, chainable API for building AI workflows
  • Streaming Support: Process streaming responses with callbacks or async iteration
  • Type Safety: Full TypeScript support with comprehensive type definitions
  • Error Handling: Proper error handling with custom error types
  • Zero Dependencies: No external runtime dependencies

FlowBuilder API

The FlowBuilder provides a fluent interface for constructing and executing flows.

Basic Usage
import { RuntypeClient } from '@runtypelabs/sdk'

const runtype = new RuntypeClient({ apiKey: 'sk-...' })

// Build and execute a flow
const result = await runtype
  .flow('Theme Generator')
  .withRecord({ name: 'Test', type: 'theme', metadata: { url: 'https://example.com' } })
  .fetchUrl({
    name: 'Capture Screenshot',
    url: '{{_record.metadata.url}}',
    fetchMethod: 'firecrawl',
    outputVariable: 'screenshot',
  })
  .prompt({
    name: 'Analyze',
    model: 'gemini-2.5-flash',
    userPrompt: 'Analyze the screenshot and extract color themes...',
    responseFormat: 'json',
  })
  .run({ streamResponse: true, flowMode: 'virtual' })

// Get specific step result
const analysis = await result.getResult('Analyze')
With Streaming Callbacks
const summary = await runtype
  .flow('My Flow')
  .prompt({ name: 'Process', model: 'gpt-4', userPrompt: '...' })
  .run(
    { streamResponse: true },
    {
      onStepStart: (event) => console.log('Starting:', event.name),
      onStepDelta: (text) => process.stdout.write(text),
      onStepComplete: (result, event) => console.log('Done:', event.name),
      onFlowComplete: (event) => console.log('Complete!'),
    }
  )
Using Existing Flows
// Reference an existing flow by ID
const result = await runtype
  .flow('Existing Flow')
  .useExistingFlow('flow_abc123')
  .withRecord({ name: 'Test', type: 'data' })
  .run({ streamResponse: true })
Standalone FlowBuilder
import { FlowBuilder } from '@runtypelabs/sdk'

// Build flow definition without a client
const flowBuilder = new FlowBuilder()
  .createFlow({ name: 'My Flow' })
  .withRecord({ name: 'Test', type: 'data' })
  .prompt({ name: 'Step 1', model: 'gpt-4', userPrompt: '...' })

// Execute with any client that implements DispatchClient interface
const flowResult = await flowBuilder.run(apiClient, {
  streamResponse: true,
  flowMode: 'virtual',
  storeResults: true,
})

// Get specific step result
const stepResult = await flowResult.getResult('Step 1')

// Or get all results
const allResults = await flowResult.getAllResults()
Available Step Methods
Method Step Type Description
.prompt() prompt AI prompt execution
.fetchUrl() fetch-url HTTP/Firecrawl fetch
.transformData() transform-data JavaScript transformation
.setVariable() set-variable Set a variable
.conditional() conditional If/else branching
.search() search Web search (Exa, etc.)
.sendEmail() send-email Send email
.sendStream() send-stream Stream message to client
.retrieveRecord() retrieve-record Load record data
.upsertRecord() upsert-record Create/update record
.vectorSearch() vector-search Semantic search
.generateEmbedding() generate-embedding Create embedding
.waitUntil() wait-until Delay or poll
.sendEvent() send-event Analytics event
.sendText() send-text SMS message
.fetchGitHub() fetch-github GitHub API
Configuration Methods
  • .createFlow({ name, description }) - Initialize flow
  • .useExistingFlow(flowId) - Use an existing flow by ID
  • .withRecord({ id?, name?, type?, metadata? }) - Set record config
  • .withMessages([...]) - Set conversation messages
  • .withOptions({ ... }) - Set default options
FlowResult Methods
  • .getResult(stepName) - Get a specific step's result
  • .getAllResults() - Get all step results as Map<string, any>
  • .getSummary() - Get FlowSummary with execution details
  • .stream(callbacks?) - Process stream with optional callbacks
  • .raw - Access raw Response for manual handling
Streaming Callbacks
interface StreamCallbacks {
  onFlowStart?: (event: FlowStartEvent) => void
  onStepStart?: (event: StepStartEvent) => void
  onStepDelta?: (text: string, event: StepDeltaEvent) => void
  onStepComplete?: (result: any, event: StepCompleteEvent) => void
  onFlowComplete?: (event: FlowCompleteEvent) => void
  onError?: (error: Error) => void
}

Traditional API Usage

The client also provides traditional endpoint-based API access:

Flows
// List flows with pagination
const flows = await runtype.flows.list({ limit: 20, cursor: 'next-page-cursor' })

// Get a specific flow
const flow = await runtype.flows.get('flow_123')

// Create a new flow
const newFlow = await runtype.flows.create({
  name: 'Analysis Flow',
  description: 'Analyzes customer data',
  prompts: [...]
})

// Update a flow
const updatedFlow = await runtype.flows.update('flow_123', { name: 'Updated Name' })

// Delete a flow
await runtype.flows.delete('flow_123')
Records
// List records with filtering
const records = await runtype.records.list({
  metadataKeys: 'company,industry',
  minFields: 5,
})

// Create a record
const record = await runtype.records.create({
  type: 'customer',
  name: 'Acme Corp',
  metadata: {
    industry: 'Technology',
    revenue: 1000000,
  },
})

// Bulk edit records
const result = await runtype.records.bulkEdit({
  recordIds: ['rec_1', 'rec_2'],
  updates: { status: 'processed' },
})
Model Configurations
// Get available models
const models = await runtype.modelConfigs.getAvailable()

// Create a model configuration
const config = await runtype.modelConfigs.create({
  provider: 'openai',
  modelId: 'gpt-4',
  apiKey: 'your-openai-key',
})

// Set as default
await runtype.modelConfigs.setDefault(config.id)
Dispatch (Atomic Operations)
// Create record and flow, then execute atomically
const result = await runtype.dispatch.execute({
  record: {
    name: 'New Customer',
    type: 'customer',
    metadata: { industry: 'Tech' },
  },
  flow: {
    name: 'Customer Analysis',
    prompts: [
      {
        name: 'Analyze Industry',
        text: 'Analyze this {{metadata.industry}} company',
        model: 'gpt-4',
        responseFormat: 'json',
      },
    ],
  },
  options: {
    streamResponse: true,
  },
})

Error Handling

import { RuntypeApiError } from '@runtypelabs/sdk'

try {
  const flow = await runtype.flows.get('invalid_id')
} catch (error) {
  if (error instanceof RuntypeApiError) {
    console.log('API Error:', error.message)
    console.log('Status Code:', error.statusCode)
    console.log('Error Data:', error.data)
  } else {
    console.log('Network or other error:', error)
  }
}

TypeScript Support

The SDK is built with TypeScript and provides full type safety:

import type {
  Flow,
  RuntypeRecord,
  Prompt,
  FlowBuilder,
  FlowResult,
  StreamCallbacks,
} from '@runtypelabs/sdk'

// All types use camelCase field names
const flow: Flow = await runtype.flows.get('flow_123')
console.log(flow.createdAt) // TypeScript knows this is a string

Configuration Options

const runtype = new RuntypeClient({
  apiKey: 'your-api-key', // Required for authenticated endpoints
  baseUrl: 'https://api.runtype.com', // Optional, defaults to production
  apiVersion: 'v1', // Optional, API version (default: 'v1')
  timeout: 30000, // Optional, request timeout in ms (default: 30000)
  headers: {
    // Optional, additional headers
    'X-Custom-Header': 'value',
  },
})

Publishing

Prerequisites
  • npm account with publish access to @runtypelabs/sdk
  • Logged in via npm login
Steps
# 1. Ensure you're on main/staging with clean working tree
git status

# 2. Build the package
cd packages/client
pnpm build

# 3. Bump version (edit package.json manually or use npm with --ignore-scripts)
npm version patch --ignore-scripts   # 0.1.0 → 0.1.1
# npm version minor --ignore-scripts # 0.1.0 → 0.2.0
# npm version major --ignore-scripts # 0.1.0 → 1.0.0

# 4. Publish to npm (pnpm handles workspace protocol correctly)
pnpm publish --access public --no-git-checks

# 5. Push version commit and tag to git
git push && git push --tags
Dry Run

To preview what will be published without actually publishing:

pnpm publish --dry-run

License

MIT

Keywords