Skip to content

hackico-ai/ruby-hati-operation

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

39 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

HatiOperation

Gem Version License: MIT

HatiOperation is a next-generation Ruby toolkit that combines powerful service orchestration with modern AI-ready architecture. Built on top of hati-command, it serves as both a traditional service aggregator and an AI-enhanced orchestrator, making it perfect for building modern applications that blend business logic with AI capabilities.

Key Features

Core Orchestration

  • Step-based execution – write each unit of work as a small service object and compose them with step
  • Implicit result propagation – methods return Success(...) or Failure(...) and are automatically unpacked
  • Fail-fast transactions – stop the chain as soon as a step fails
  • Dependency injection (DI) – override steps at call-time for ultimate flexibility
  • Macro DSL – declaratively configure validation, error mapping, transactions and more
  • Service aggregation – orchestrate multiple services into cohesive business operations

AI-Ready Architecture

  • Tool Integration – seamlessly integrate AI services and LLM tools
  • Safety Boundaries – built-in guardrails for AI operations
  • Action Composition – chain multiple AI actions safely
  • State Management – track and manage AI agent state

Development Acceleration

  • Structured Patterns – clear patterns for both human and AI comprehension
  • Predictable Flow – consistent operation structure for better maintainability
  • Self-Documenting – clear step definitions aid both human and AI understanding
  • Context Awareness – easy access to operation context for all services

Table of Contents

  1. Key Features
  2. Architecture
  3. Installation
  4. Quick Start
  5. Step DSL
  6. Dependency Injection
  7. Alternative DSL Styles
  8. Testing
  9. Authors
  10. Development
  11. Contributing
  12. License
  13. Code of Conduct

Architecture

HatiOperation builds on top of hati-command and implements a versatile architecture that supports both traditional service aggregation and AI-enhanced operations:

┌─────────────────────────────────────────────────────────────┐
│                    HatiOperation                            │
│            (Universal Service Orchestrator)                 │
├─────────────────────────────────────────────────────────────┤
│                                                             │
│  Traditional Services        AI/ML Services                 │
│  ┌─────────────┐            ┌─────────────┐                 │
│  │  Business   │            │   LLM       │                 │
│  │  Logic      │            │   Tools     │                 │
│  └─────────────┘            └─────────────┘                 │
│                                                             │
│  ┌─────────────┐            ┌─────────────┐                 │
│  │  Data       │            │   Agent     │                 │
│  │  Services   │            │   Actions   │                 │
│  └─────────────┘            └─────────────┘                 │
│                                                             │
│  ┌─────────────┐            ┌─────────────┐                 │
│  │  External   │            │   Safety    │                 │
│  │  APIs       │            │   Guards    │                 │
│  └─────────────┘            └─────────────┘                 │
│                                                             │
├─────────────────────────────────────────────────────────────┤
│                   hati-command                              │
│                 (Foundation Layer)                          │
└─────────────────────────────────────────────────────────────┘

This dual-purpose architecture allows you to:

  • Compose traditional business services with robust error handling and transactions
  • Integrate AI capabilities with built-in safety mechanisms
  • Mix and match both paradigms in the same operation
  • Maintain clean separation of concerns while sharing common infrastructure

Installation

Add HatiOperation to your Gemfile and bundle:

# Gemfile
gem 'hati_operation'
bundle install

Alternatively:

gem install hati_operation

Quick Start

HatiOperation can be used for both traditional business operations and AI-enhanced services. Here are examples of both:

Traditional Business Operation

# app/controllers/api/v1/withdrawal_controller.rb
class Api::V1::WithdrawalController < ApplicationController
  def create
    result = Withdrawal::Operation::Create.call(params: params.to_unsafe_h)
    run_and_render(result)
  end

  private

  def run_and_render(result)
    if result.success?
      render json: TransferSerializer.new.serialize(result.value), status: :created
    else
      error = ApiError.new(result.value)
      render json: error.to_json, status: error.status
    end
  end
end

# app/operations/withdrawal/operation/create.rb
class Withdrawal::Operation::Create < HatiOperation::Base
  # Wrap everything in DB transaction
  ar_transaction :funds_transfer_transaction!

  def call(params:)
    params = step MyApiContract.call(params), err: ApiErr.call(422)
    transfer = step funds_transfer_transaction(params[:account_id])
    EventBroadcast.new.stream(transfer.to_event)

    transfer.meta
  end

  def funds_transfer_transaction(acc_id)
    acc = Account.find_by(find_by: acc_id).presence : Failure!(err: ApiErr.call(404))

    withdrawal = step WithdrawalService.call(acc), err: ApiErr.call(409)
    transfer = step ProcessTransferService.call(withdrawal), err: ApiErr.call(503)

    Success(transfer)
  end
end

AI-Enhanced Operation

# app/operations/ai/content_generation.rb
class AI::Operation::ContentGeneration < HatiOperation::Base
  # Register safety boundaries
  safety_guard :content_filter
  rate_limit max_tokens: 1000

  step validator: ContentValidator
  step generator: LLMService
  step filter: ContentFilter
  step formatter: OutputFormatter

  def call(params:)
    # Validate input and prepare prompt
    input = step validator.call(params[:prompt])

    # Generate content with safety checks
    content = step generator.call(input), err: AIErr.call(503)
    filtered = step filter.call(content), err: AIErr.call(422)

    # Format and return
    step formatter.call(filtered)
  end
end

# Usage in controller
class Api::V1::ContentController < ApplicationController
  def create
    result = AI::Operation::ContentGeneration.call(params: params.to_unsafe_h) do
      # Override services for different models/providers
      step generator: OpenAIService
      step filter: CustomContentFilter
    end

    render_result(result)
  end
end

Base Operation Configuration

# Common configuration for API operations
class ApiOperation < HatiOperation::Base
  operation do
    unexpected_err ApiErr.call(500)
  end
end

# Common configuration for AI operations
class AIOperation < HatiOperation::Base
  operation do
    unexpected_err AIErr.call(500)
    safety_guard :content_filter
    rate_limit true
  end
end

Step DSL

The DSL gives you fine-grained control over every stage of the operation:

Core DSL Methods

  • step – register a dependency service
  • params – validate/transform incoming parameters
  • on_success – handle successful operation results
  • on_failure – map and handle failure results

Extended Configuration

See: hati-command for all configuration options

  • ar_transaction – execute inside database transaction
  • fail_fast – configure fail-fast behavior
  • failure – set default failure handling
  • unexpected_err – configure generic error behavior

Dependency Injection

At runtime you can swap out any step for testing, feature-flags, or different environments:

result = Withdrawal::Operation::Create.call(params) do
  step broadcast: DummyBroadcastService
  step transfer:  StubbedPaymentProcessor
end

Alternative DSL Styles

Declarative Style

Prefer more declarative code? Use the class-level DSL:

class Withdrawal::Operation::Create < ApiOperation
  params CreateContract, err: ApiErr.call(422)

  ar_transaction :funds_transfer_transaction!

  step withdrawal: WithdrawalService, err: ApiErr.call(409)
  step transfer: ProcessTransferService, err: ApiErr.call(503)
  step broadcast: Broadcast

  on_success SerializerService.call(Transfer, status: 201)
  on_failure ApiErrorSerializer

  # requires :params keyword to access overwritten params
  # same as params = step CreateContract.call(params), err: ApiErr.call(422)
  def call(params:)
    transfer = step funds_transfer_transaction!(params[:account_id])
    broadcast.new.stream(transfer.to_event)
    transfer.meta
  end

  def funds_transfer_transaction!(acc_id)
    acc = step(err: ApiErr.call(404)) { User.find(id) }

    withdrawal = step withdrawal.call(acc)
    transfer = step transfer.call(withdrawal)
    Success(transfer)
  end
end

class Api::V2::WithdrawalController < ApiController
  def create
    run_and_render Withdrawal::Operation::Create
  end

  private

  def run_and_render(operation, &block)
   render JsonResult.prepare operation.call(params.to_unsafe_h).value
  end
end

Full-Stack DI Example

class Api::V2::WithdrawalController < ApplicationController
  def create
    run_and_render Withdrawal::Operation::Create.call(params.to_unsafe_h) do
      step broadcast: API::V2::BroadcastService
      step transfer:  API::V2::PaymentProcessorService
      step serializer: ExtendedTransferSerializer
    end
  end
end

Testing

Run the test-suite with:

bundle exec rspec

HatiOperation is fully covered by RSpec. See spec/ for reference examples including stubbed services and DI.

Authors

Development

After checking out the repo, run bin/setup to install dependencies. Then, run rake spec to run the tests. You can also run bin/console for an interactive prompt that will allow you to experiment.

To install this gem onto your local machine, run bundle exec rake install. To release a new version, update the version number in version.rb, and then run bundle exec rake release, which will create a git tag for the version, push git commits and the created tag, and push the .gem file to rubygems.org.

Contributing

Bug reports and pull requests are welcome on GitHub at https://github.com/hackico-ai/hati-command. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the code of conduct.

License

The gem is available as open source under the terms of the MIT License.

Code of Conduct

Everyone interacting in the HatCommand project's codebases, issue trackers, chat rooms and mailing lists is expected to follow the code of conduct.

About

Encapsulates business logic in isolated, reusable operation classes for clarity and testability.

Topics

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages