Project

agentic

0.0
A long-lived project that still receives updates
Easily build, manage, deploy, and run self-contained purpose-driven AI Agents.
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
2025
 Dependencies

Runtime

 Project Readme

Agentic

A Ruby gem for building and running AI agents in a plan-and-execute fashion. Agentic provides a simple command-line tool and library to build, manage, deploy, and run purpose-driven AI agents using OpenAI's LLM API.

What's New in v0.2.0

🚀 Agent Self-Assembly System - Agents can now dynamically construct themselves based on task requirements
🎯 Capability System - Rich specification and versioning system for agent capabilities
💾 Persistent Agent Store - Save and reuse agents across sessions
🔧 Enhanced CLI - Comprehensive command-line interface with agent and capability management
📊 Learning System - Agents improve over time through execution history analysis
🎨 Real-time Feedback - Progress bars, spinners, and colorized output for better user experience

Demo Video

Installation

Install the gem and add to the application's Gemfile by executing:

$ bundle add agentic

If bundler is not being used to manage dependencies, install the gem by executing:

$ gem install agentic

Usage

Command-Line Interface

Agentic comes with a rich command-line interface featuring colored output, spinners for long-running tasks, and progress tracking:

# Display version information
$ agentic version

# Configuration Management
$ agentic config init                               # Initialize configuration
$ agentic config init --global                      # Initialize global configuration
$ agentic config list                               # List all configuration settings
$ agentic config get model                          # Get a specific configuration value
$ agentic config set api_token=your_openai_api_key  # Set your OpenAI API token
$ agentic config set model=gpt-4o-mini             # Configure the default model

# Plan Creation and Execution
$ agentic plan "Generate a market research report on AI trends"          # Create a plan
$ agentic plan "Write a blog post about Ruby" --save plan.json           # Save plan to file
$ agentic plan "Research quantum computing" --output json                # Output in JSON format
$ agentic plan "Analyze market trends" --model gpt-4o                    # Use a specific model
$ agentic plan "Create documentation" --execute                          # Create and execute immediately
$ agentic plan "Research topics" --no-interactive                        # Skip interactive prompts

$ agentic execute --plan plan.json                  # Execute a saved plan
$ agentic execute --from-stdin                      # Read plan from stdin
$ agentic execute --max-concurrency 5               # Limit concurrent tasks
$ agentic execute --file results.json               # Save results to specific file

# Agent Management
$ agentic agent list                                # List available agents
$ agentic agent list --detailed                    # List with detailed information
$ agentic agent create "ResearchAgent" \            # Create a new agent
    --role="Research Assistant" \
    --purpose="Conduct thorough research" \
    --capabilities=text_generation,web_search
$ agentic agent show "ResearchAgent"                # Show agent details
$ agentic agent build "ResearchAgent"               # Build an agent from storage
$ agentic agent delete "ResearchAgent"              # Delete an agent

# Capability Management
$ agentic capabilities list                         # List available capabilities
$ agentic capabilities show text_generation         # Show capability details
$ agentic capabilities search generation            # Search for capabilities

The CLI provides real-time feedback with spinners for long-running operations, colored status updates, and detailed progress tracking. It supports both global and project-specific configuration, allowing you to customize the behavior for different projects.

Programmatic API

To use Agentic in your Ruby code:

Basic Usage

require 'agentic'

# Configure your OpenAI API key
Agentic.configure do |config|
  config.access_token = 'your_openai_api_key'
end

# Create a TaskPlanner instance with a goal
planner = Agentic::TaskPlanner.new("Write a blog post about Ruby on Rails")

# Generate the plan
plan = planner.plan

# Display the plan
puts plan.to_s

# Or access the structured data
plan.tasks.each do |task|
  puts "Task: #{task.description}"
  puts "Agent: #{task.agent.name}"
end

Working with Agents

# Create an agent with specific configuration
agent = Agentic::Agent.build do |a|
  a.name = "ResearchAgent"
  a.role = "Research Assistant"
  a.instructions = "Conduct thorough research on the given topic"
end

# Configure the LLM
config = Agentic::LlmConfig.new(
  model: "gpt-4o-mini",
  temperature: 0.7
)

# Create a task
task = Agentic::Task.new(
  description: "Research the latest trends in Ruby on Rails",
  agent_spec: {
    "name" => "ResearchAgent",
    "description" => "An agent that performs research",
    "instructions" => "Research the given topic thoroughly"
  }
)

# Execute the task with the agent
result = task.perform(agent)

# Check the result
if result.successful?
  puts "Task completed successfully!"
  puts result.output
else
  puts "Task failed: #{result.failure.message}"
end

Plan Orchestration

# Create an orchestrator
orchestrator = Agentic::PlanOrchestrator.new(
  concurrency_limit: 5,
  continue_on_failure: true
)

# Add tasks to the orchestrator
tasks.each do |task|
  orchestrator.add_task(task)
end

# Create an agent provider
agent_provider = Agentic::DefaultAgentProvider.new

# Execute the plan
result = orchestrator.execute_plan(agent_provider)

# Process the results
if result.successful?
  puts "Plan executed successfully!"
else
  puts "Plan execution had issues: #{result.status}"
  result.results.each do |task_id, task_result|
    if task_result.failed?
      puts "Task #{task_id} failed: #{task_result.failure.message}"
    end
  end
end

Extension System

Agentic includes a powerful Extension System to help integrate with external systems and customize the framework's behavior. The Extension System consists of three main components:

Domain Adapters

Domain Adapters let you customize Agentic's behavior for specific domains like healthcare, finance, or legal:

# Create a domain adapter for healthcare
adapter = Agentic::Extension.domain_adapter("healthcare")

# Add domain-specific knowledge
adapter.add_knowledge(:terminology, {
  terms: ["patient", "diagnosis", "treatment"],
  specialty: "cardiology"
})

# Create a custom prompt adapter
prompt_adapter = ->(prompt, context) {
  specialty = context[:domain_knowledge][:terminology][:specialty]
  "#{prompt} [Adapted for #{context[:domain]} #{specialty}]"
}

# Register the adapter
adapter.register_adapter(:prompt, prompt_adapter)

# Apply adaptation to a prompt
adapted_prompt = adapter.adapt(:prompt, "Describe the symptoms")
# => "Describe the symptoms [Adapted for healthcare cardiology]"

Protocol Handlers

Protocol Handlers standardize connections to external systems and APIs:

# Get the protocol handler
handler = Agentic::Extension.protocol_handler(
  default_headers: { "User-Agent" => "AgenticApp/1.0" }
)

# Create and register a protocol implementation
http_protocol = Object.new
def http_protocol.send_request(endpoint, options)
  # Implement HTTP request logic
  { status: 200, body: "Response data" }
end

# Register the protocol
handler.register_protocol(:http, http_protocol, { timeout: 30 })

# Send a request
response = handler.send_request(:http, "/api/data", {
  method: "GET",
  headers: { "Accept" => "application/json" }
})

Plugin Manager

The Plugin Manager handles third-party extensions and their lifecycle:

# Get the plugin manager
manager = Agentic::Extension.plugin_manager

# Register a plugin
plugin = MyPlugin.new
manager.register("my_plugin", plugin, { version: "1.0.0" })

# Get and use a plugin
if plugin = manager.get("my_plugin")
  result = plugin.call(arg1, arg2)
end

# Disable a plugin
manager.disable("my_plugin")

Agent Specification and Task Definition

Agentic provides structured representations for agents and tasks through several key value objects:

Agent Specification

The AgentSpecification defines the requirements for an agent:

# Create an agent specification
agent_spec = Agentic::AgentSpecification.new(
  name: "ResearchAgent",
  description: "An agent that performs research",
  instructions: "Research the given topic thoroughly"
)

# Convert to a hash representation
hash = agent_spec.to_h

# Create from a hash representation
agent_spec_from_hash = Agentic::AgentSpecification.from_hash(hash)

Task Definition

The TaskDefinition defines a task to be performed by an agent:

# Create a task definition
task_def = Agentic::TaskDefinition.new(
  description: "Research AI trends",
  agent: agent_spec
)

# Convert to a hash representation
hash = task_def.to_h

# Create from a hash representation
task_def_from_hash = Agentic::TaskDefinition.from_hash(hash)

Execution Plan

The ExecutionPlan represents a plan with tasks and expected answer format:

# Create an expected answer format
expected_answer = Agentic::ExpectedAnswerFormat.new(
  format: "PDF",
  sections: ["Summary", "Trends", "Conclusion"],
  length: "10 pages"
)

# Create an execution plan
plan = Agentic::ExecutionPlan.new([task_def], expected_answer)

# Convert to a formatted string
puts plan.to_s

# Convert to a hash representation
hash = plan.to_h

Agent Configuration

The AgentConfig provides a configuration object for agents:

# Create an agent configuration
config = Agentic::AgentConfig.new(
  name: "ResearchAgent",
  role: "Research Assistant",
  backstory: "You are an expert researcher with decades of experience",
  tools: ["web_search", "document_processor"],
  llm_config: Agentic::LlmConfig.new(model: "gpt-4o-mini")
)

# Access configuration properties
puts config.name
puts config.role

# Convert to a hash representation
hash = config.to_h

Agent Capabilities System

Agentic features a powerful Capability System that enables dynamic agent composition, self-assembly, and persistence. The system allows agents to be constructed with precisely the capabilities they need for specific tasks, and to be stored for future reuse.

Capability Registry

The capability registry manages capability specifications and providers:

# Define a capability specification
text_gen_capability = Agentic::CapabilitySpecification.new(
  name: "text_generation",
  description: "Generates text based on a prompt",
  version: "1.0.0",
  inputs: {
    prompt: { type: "string", required: true, description: "The prompt to generate text from" }
  },
  outputs: {
    response: { type: "string", description: "The generated text" }
  }
)

# Create a provider for the capability
text_gen_provider = Agentic::CapabilityProvider.new(
  capability: text_gen_capability,
  implementation: ->(inputs) { { response: "Generated text for: #{inputs[:prompt]}" } }
)

# Register the capability with the system
Agentic.register_capability(text_gen_capability, text_gen_provider)

Agent Assembly Engine

The assembly engine dynamically constructs agents based on task requirements:

# Define a task
task = Agentic::Task.new(
  description: "Generate a report on AI trends",
  agent_spec: Agentic::AgentSpecification.new(
    name: "Report Generator",
    description: "An agent that generates reports",
    instructions: "Generate a comprehensive report on the topic"
  ),
  input: {
    topic: "AI trends in 2023",
    format: "markdown"
  }
)

# Assemble an agent for the task
agent = Agentic.assemble_agent(task)

# The agent will automatically have capabilities like "text_generation"
# based on the task requirements

Agent Persistence

Agents can be stored and retrieved for future use:

# Store an agent for future use
agent_id = Agentic.agent_store.store(agent, name: "report_generator")

# Later, retrieve the agent by name
stored_agent = Agentic.agent_store.build_agent("report_generator")

# Or retrieve by ID
stored_agent = Agentic.agent_store.build_agent(agent_id)

# List all stored agents
agents = Agentic.agent_store.all

Capability Composition

Capabilities can be composed into higher-level capabilities:

registry = Agentic.agent_capability_registry

# Compose multiple capabilities into a new one
registry.compose(
  "comprehensive_report",
  "Generates a comprehensive report with research and formatting",
  "1.0.0",
  [
    { name: "text_generation", version: "1.0.0" },
    { name: "data_analysis", version: "1.0.0" }
  ],
  ->(providers, inputs) {
    # Implementation that uses both capabilities
    analysis = providers[1].execute(data: inputs[:data])
    report = providers[0].execute(prompt: "Generate a report on: #{analysis[:summary]}")
    { report: report[:response], analysis: analysis }
  }
)

# Use the composed capability
agent.add_capability("comprehensive_report")
result = agent.execute_capability("comprehensive_report", { data: { ... } })

Learning System

Agentic features a Learning System that enables agents to improve over time by capturing execution metrics, recognizing patterns, and optimizing strategies. The Learning System consists of three main components:

Execution History Store

The ExecutionHistoryStore captures and stores execution metrics and performance data:

# Create a history store
history_store = Agentic::Learning::ExecutionHistoryStore.new(
  storage_path: "~/.agentic/history",
  anonymize: true,
  retention_days: 30
)

# Record task execution metrics
history_store.record_execution(
  task_id: "task-123",
  agent_type: "research_agent",
  duration_ms: 1500,
  success: true,
  metrics: { tokens_used: 2000, quality_score: 0.85 }
)

# Query execution history
research_tasks = history_store.get_history(agent_type: "research_agent", success: true)

# Calculate metrics
avg_tokens = history_store.get_metric(:tokens_used, { agent_type: "research_agent" }, :avg)

Pattern Recognizer

The PatternRecognizer analyzes execution history to identify patterns and optimization opportunities:

# Create a pattern recognizer
recognizer = Agentic::Learning::PatternRecognizer.new(
  history_store: history_store,
  min_sample_size: 10
)

# Analyze agent performance
patterns = recognizer.analyze_agent_performance("research_agent")

# Analyze correlations between properties
correlation = recognizer.analyze_correlation(:duration_ms, :tokens_used)

# Get optimization recommendations
recommendations = recognizer.recommend_optimizations("research_agent")

Strategy Optimizer

The StrategyOptimizer generates improvements for prompts, parameters, and task sequences:

# Create a strategy optimizer
optimizer = Agentic::Learning::StrategyOptimizer.new(
  pattern_recognizer: recognizer,
  history_store: history_store,
  llm_client: llm_client # Optional, for LLM-enhanced optimizations
)

# Optimize a prompt template
improved_prompt = optimizer.optimize_prompt_template(
  "Research the topic: {topic}",
  "research_agent"
)

# Optimize LLM parameters
improved_params = optimizer.optimize_llm_parameters(
  { temperature: 0.7, max_tokens: 2000 },
  "research_agent",
  optimization_strategy: :balanced
)

# Generate performance report
report = optimizer.generate_performance_report("research_agent")

Integrating with Plan Orchestrator

The Learning System can be automatically integrated with the PlanOrchestrator:

# Create the learning system
learning_system = Agentic::Learning.create(
  storage_path: "~/.agentic/history",
  llm_client: llm_client,
  auto_optimize: false
)

# Create a plan orchestrator
orchestrator = Agentic::PlanOrchestrator.new

# Register the learning system with the orchestrator
Agentic::Learning.register_with_orchestrator(orchestrator, learning_system)

# The orchestrator will now automatically record execution metrics

Configuration

Setting up the OpenAI API Key

You can configure the OpenAI API key in several ways:

  1. Environment variable:

    export OPENAI_ACCESS_TOKEN="your_api_key"
  2. Configuration file: Create .agentic.yml in your project directory or home directory:

    api_token: "your_api_key"
    model: "gpt-4o-mini"
  3. In your Ruby code:

    Agentic.configure do |config|
      config.access_token = "your_api_key"
    end

LLM Configuration

You can customize the LLM behavior:

config = Agentic::LlmConfig.new(
  model: "gpt-4o-mini",
  max_tokens: 500,
  temperature: 0.7,
  top_p: 1.0,
  frequency_penalty: 0,
  presence_penalty: 0
)

# Use in TaskPlanner
planner = Agentic::TaskPlanner.new("Write a blog post", config)

# Or with LlmClient directly
client = Agentic::LlmClient.new(config)

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.

Running Tests

Agentic includes a comprehensive test suite with both unit tests and integration tests. To run all tests:

rake spec

To run specific test categories:

# Run just integration tests
rspec spec/integration/

# Run a specific integration test file
rspec spec/integration/plan_orchestrator_integration_spec.rb

# Run with verbose output
rspec spec/integration/ --format documentation

The integration tests cover real-world scenarios including:

  • Complex orchestration patterns with dependencies
  • Learning system's pattern recognition capabilities
  • Agent specification and task definition interactions
  • Timeout and retry behaviors
  • Error handling in complex scenarios

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/codenamev/agentic. 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 Agentic project's codebases, issue trackers, chat rooms and mailing lists is expected to follow the code of conduct.