An open API service indexing awesome lists of open source software.

https://github.com/mrjonesbot/sage

LLM powered reporting
https://github.com/mrjonesbot/sage

business-intelligence charts sql

Last synced: 27 days ago
JSON representation

LLM powered reporting

Awesome Lists containing this project

README

          

# Sage

![Sage Query Interface](screenshots/sage-query-interface.png)

> **Note:** This project is pre-v1 and is subject to frequent changes.

**Natural language reporting to help your team build accurate reports, faster.**

Sage is a Rails engine built on top of the excellent [Blazer](https://github.com/ankane/blazer) gem, adding an LLM interface to make data exploration accessible via natural language.

## Requirements

Rails 7.1+ is recommended, compatability with older versions not guaranteed.

Sage relies on `turbo-rails` and `stimulus-rails` to render the dashboard. These gems should already be included in most modern Rails applications. If not, add them to your Gemfile:

```ruby
gem "turbo-rails"
gem "stimulus-rails"
```

Refer to the [stimulus-rails installation page](https://github.com/hotwired/stimulus-rails) to get started.

## Installation

Add Sage to your application's Gemfile:

```ruby
gem "sage-rails", require: 'sage'
```

Run bundle install:
```bash
$ bundle install
```

## Getting Started

Run the install generator to set up Sage in your Rails application:

```bash
$ rails generate sage:install
```

This generator will:
- Install Blazer if not already present
- Mount Sage at `/sage` in your routes
- Create an initializer at `config/initializers/sage.rb`
- Set up database migrations for message storage

After installation, run the migrations:
```bash
$ rails db:migrate
```

### Sprockets

If using sprockets, add this line to your app/javascript/application.js file:
```js
import "sage/application";
```

## LLM Configuration

Sage supports both Anthropic Claude and OpenAI models for SQL generation. Configure your preferred AI service in `config/initializers/sage.rb`:

### Using Anthropic

```ruby
Sage.configure do |config|
config.provider = :anthropic

# API key configuration
config.anthropic_api_key = Rails.application.credentials.dig(:anthropic, :api_key) ||
ENV["ANTHROPIC_API_KEY"]

# Model selection (defaults to claude-3-opus-20240229)
config.anthropic_model = "claude-3-opus-20240229"
end
```

### Using OpenAI

```ruby
Sage.configure do |config|
config.provider = :openai

# API Key Configuration
config.openai_api_key = Rails.application.credentials.dig(:openai, :api_key) ||
ENV["OPENAI_API_KEY"]

# Model selection
config.openai_model = "gpt-4" # or "gpt-3.5-turbo" for faster responses
end
```

## Blazer

Sage is built on top of Blazer and honors all existing Blazer configurations.

- **Database Setup**: Configure your database connections through Blazer
- **Multiple Data Sources**: Switch between different databases seamlessly
- **Smart Variables**: Use dynamic variables in generated queries
- **Checks & Alerts**: Set up automated monitoring on your queries
- **Auditing**: Track query usage and performance
- **Security**: Leverage Blazer's authentication and authorization features

For detailed information on Blazer-specific features, refer to the [Blazer documentation](https://github.com/ankane/blazer).

## Database Context

Sage introspects your database schema to provide context for more accurate SQL generation.

### Multiple Data Sources

If you have multiple databases, Sage will use the appropriate schema for each:

When querying different data sources in Blazer, Sage will switch schema context.

## Model Scope Context

Sage introspects your Rails model scopes to understand common query patterns, dramatically improving the accuracy of generated SQL queries.

### Example

Given these model scopes:

```ruby
# app/models/user.rb
class User < ApplicationRecord
scope :active, -> { where(status: 'active') }
scope :recent, -> { where('created_at > ?', 30.days.ago) }
scope :with_orders, -> { joins(:orders).distinct }
scope :high_value, -> {
joins(:orders)
.group('users.id')
.having('SUM(orders.total) > ?', 1000)
}
end

# app/models/order.rb
class Order < ApplicationRecord
scope :completed, -> { where(status: 'completed') }
scope :recent, -> { where('created_at > ?', 7.days.ago) }
scope :high_value, -> { where('total > ?', 500) }
end
```

When prompted: *"Show me high-value customers from the last month"*

Sage understands:
- "high-value customers" → Use the `high_value` scope pattern from User model
- "last month" → Similar to the `recent` scope pattern, adjust the time range
- Combines these patterns to generate accurate SQL with proper JOINs and aggregations

### Benefits

1. **Business Logic Awareness**: Scopes encode your business rules (what makes a customer "active" or "high-value")
2. **Aggregation Patterns**: Complex scopes with GROUP BY and HAVING clauses guide report generation
3. **Consistency**: Generated queries follow the same patterns as your application code

Scopes now serve dual purposes:
1. Reusable query logic in your Rails application
2. Documentation for report generation

## Development

After checking out the repo:

```bash
$ bundle install
$ cd test/dummy
$ rails db:create
$ rails db:migrate
$ rails server
```

Visit http://localhost:3000/sage.

## Testing

Run the test suite:

```bash
$ rails test
```

## Troubleshooting

### API Key Issues
- Verify your API key is correctly set in credentials or environment variables
- Check Rails logs for authentication errors
- Ensure your API key has appropriate permissions

### Query Generation Issues
- Verify database schema is being loaded (check logs for schema context)
- Ensure model files are in standard Rails locations (`app/models/`)
- Check that Blazer is properly configured and can execute queries

## Contributing

Bug reports and pull requests are welcome on GitHub. This project is intended to be a safe, welcoming space for collaboration.

## License

The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).