Stellwerk
A standalone Ruby gem for evaluating pre-compiled Stellwerk flows without any Rails or ActiveRecord dependencies.
What is Stellwerk?
Stellwerk is a visual platform for building decision flows and business logic without code. Design complex calculations, conditional branching, and data transformations using an intuitive drag-and-drop interface, then export your flows as compiled JSON to run anywhere.
This gem lets you execute those compiled flows in any Ruby application.
Installation
Add this line to your application's Gemfile:
gem 'stellwerk-ruby'
And then execute:
bundle install
Or install it yourself as:
gem install stellwerk-ruby
Quick Start
require 'stellwerk'
# Configure your API key (required)
Stellwerk.configure do |config|
config.api_key = ENV['STELLWERK_API_KEY']
end
# Load and execute a flow
flow = Stellwerk::Flow.load('pricing.compiled.json')
result = flow.execute(quantity: 10, price: 25.00)
if result.success?
puts "Total: #{result.outputs[:total]}"
else
puts "Errors: #{result.errors}"
end
Configuration
Required: API Key
All flow executions require a valid API key. Get your key from stellwerk.io.
Stellwerk provides two types of API keys:
| Key Type | Prefix | Purpose | Quota |
|---|---|---|---|
| Test | sk_test_... |
Development and testing | Not counted |
| Live | sk_live_... |
Production use | Counted against plan |
Use test keys during development to avoid consuming your quota. Switch to live keys when deploying to production.
Stellwerk.configure do |config|
# Use test key in development, live key in production
config.api_key = ENV['STELLWERK_API_KEY']
end
# Or use the shorthand
Stellwerk.api_key = ENV['STELLWERK_API_KEY']
Tip: Set different environment variables per environment:
# .env.development
STELLWERK_API_KEY=sk_test_your_test_key
# .env.production
STELLWERK_API_KEY=sk_live_your_live_key
Full Configuration Options
Stellwerk.configure do |config|
# Required: Your API key from stellwerk.io
config.api_key = ENV['STELLWERK_API_KEY']
# Optional: API endpoint (default: https://stellwerk.io)
config.api_url = 'https://stellwerk.io'
# Optional: Interval for batch reporting executions (default: 60 seconds)
config.sync_interval = 60
# Optional: How long to allow offline operation (default: 86400 = 24 hours)
config.offline_grace_period = 86_400
# Optional: Max executions during offline grace period (default: 100)
config.offline_grace_executions = 100
# Optional: Logger for debugging
config.logger = Logger.new(STDOUT)
end
Usage Examples
Basic Execution
flow = Stellwerk::Flow.load('calculator.compiled.json')
result = flow.execute(x: 10, y: 20)
puts result.outputs[:sum] # => 30
Error Handling
flow = Stellwerk::Flow.load('pricing.compiled.json')
begin
result = flow.execute(params)
if result.success?
process(result.outputs)
else
# Flow executed but returned errors (validation, business logic)
log_errors(result.errors)
end
rescue Stellwerk::LicenseError => e
# API key missing or invalid
puts "License error: #{e.}"
rescue Stellwerk::QuotaExceededError => e
# Execution limit reached
puts "Quota exceeded: #{e.}"
rescue Stellwerk::ApiError => e
# Server communication error
puts "API error: #{e.} (status: #{e.status_code})"
end
Batch Processing
flow = Stellwerk::Flow.load('invoice.compiled.json')
invoices.each do |invoice|
result = flow.execute(invoice.to_h)
if result.success?
invoice.update!(
subtotal: result.outputs[:subtotal],
tax: result.outputs[:tax],
total: result.outputs[:total]
)
end
end
# Executions are batched and reported automatically
Checking License Status
# Check if properly licensed before processing
if Stellwerk.licensed?
process_flows
else
puts "Please configure a valid API key"
end
# Access license details
license = Stellwerk.license
puts "Plan: #{license.plan}"
puts "Limit: #{license.execution_limit}"
puts "Used: #{license.executions_used}"
Direct Evaluator Usage
For advanced use cases, you can use the evaluator directly:
require 'json'
json = JSON.parse(File.read('flow.json'))
result = Stellwerk::Evaluator.call(
compiled_json: json,
params: { x: 10, y: 20 },
metadata: { source: 'api', user_id: 123 }
)
puts result.outputs # Output values
puts result.context # Full execution context
puts result.applied_nodes # Executed node IDs
Offline Mode
If the Stellwerk server becomes unreachable after a successful license validation, the SDK enters an offline grace period:
- Default duration: 24 hours
- Default execution limit: 100 executions
During offline mode, executions are tracked locally and reported when connectivity is restored.
# Check if operating in offline mode
if Stellwerk.license.offline?
puts "Operating in offline mode"
end
Result Object
Execution returns a Stellwerk::Result object:
result = flow.execute(params)
result.success? # => true/false
result.failure? # => true/false
result.outputs # => Hash of output values
result.errors # => Array of error messages/hashes
result.applied_nodes # => Array of executed node IDs
result.context # => Full execution context
Compiled JSON Format
The gem expects compiled flow JSON in this structure:
{
"version": "1.0",
"compiled_at": "2026-01-31T12:00:00Z",
"entry_node_ids": ["node-1"],
"nodes": {
"node-1": {
"id": "node-1",
"name": "Start",
"type": "start",
"config": { "inputs": [...] }
}
},
"adjacency": {
"node-1": [{ "to": "node-2", "branch": null }]
},
"reverse_adjacency": {
"node-2": ["node-1"]
},
"sub_flows": {
"flow-uuid": { ... embedded sub-flow ... }
}
}
Node Types
The evaluator supports the following node types:
- start: Entry point with input validation
- calculate: Formula evaluation using Dentaku
- condition: Boolean branching (true/false)
- switch: Multi-case branching
- merge: Joins multiple branches
- map: Iterates over arrays with sub-flow execution
- end: Output template processing
Built-in Functions
The gem includes collection functions for use in formulas:
Aggregation
SUM(array)orSUM(a, b, c)COUNT(array)MIN(array)/MAX(array)AVERAGE(array)orAVG(array)
Array Operations
FIRST(array)/LAST(array)TAKE(array, n)DISTINCT(array)PROJECT(array, "field")- Extract field from array of hashes
Higher-Order Functions
MAP(array, "expression")- Transform elementsFILTER(array, "predicate")- Filter elementsREDUCE(array, initial, "expression")- Reduce to single valueSUMIF(array, "predicate", "projection")- Conditional sumCOUNTIF(array, "predicate")- Conditional count
Troubleshooting
"API key is required"
You must configure an API key before executing flows:
Stellwerk.configure do |config|
config.api_key = ENV['STELLWERK_API_KEY']
end
Get your API key from stellwerk.io.
"Invalid API key"
Your API key is not recognized. Verify:
- The key is correctly copied (no extra spaces)
- The key is active in your Stellwerk dashboard
- You're using the correct key type (
sk_test_...for development,sk_live_...for production)
"Execution limit reached"
You've exceeded your plan's monthly execution quota. Options:
- Wait for the next billing cycle
- Upgrade your plan at stellwerk.io
"Offline execution limit reached"
During offline mode, you've exceeded the allowed offline executions. Restore network connectivity to continue.
Debug Mode
Enable logging to see detailed execution information:
Stellwerk.configure do |config|
config.api_key = ENV['STELLWERK_API_KEY']
config.logger = Logger.new(STDOUT)
config.logger.level = Logger::DEBUG
end
Flow Validation Errors
If result.failure? returns true, check result.errors for details:
result = flow.execute(params)
if result.failure?
result.errors.each do |error|
puts "Error: #{error}"
end
end
Common causes:
- Missing required input parameters
- Invalid data types
- Formula evaluation errors
Development
After checking out the repo, run:
bundle install
bundle exec rspec
License
The gem is available as open source under the terms of the MIT License.