soka-rails 0.0.1.beta4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/.rspec +3 -0
- data/.rubocop.yml +367 -0
- data/CHANGELOG.md +41 -0
- data/CLAUDE.md +243 -0
- data/DESIGN.md +957 -0
- data/LICENSE +21 -0
- data/README.md +420 -0
- data/REQUIREMENT.md +308 -0
- data/Rakefile +12 -0
- data/SPEC.md +420 -0
- data/app/soka/agents/application_agent.rb +5 -0
- data/app/soka/tools/application_tool.rb +5 -0
- data/lib/generators/soka/agent/agent_generator.rb +60 -0
- data/lib/generators/soka/agent/templates/agent.rb.tt +25 -0
- data/lib/generators/soka/agent/templates/agent_spec.rb.tt +31 -0
- data/lib/generators/soka/install/install_generator.rb +39 -0
- data/lib/generators/soka/install/templates/application_agent.rb +5 -0
- data/lib/generators/soka/install/templates/application_tool.rb +5 -0
- data/lib/generators/soka/install/templates/soka.rb +31 -0
- data/lib/generators/soka/tool/templates/tool.rb.tt +26 -0
- data/lib/generators/soka/tool/templates/tool_spec.rb.tt +48 -0
- data/lib/generators/soka/tool/tool_generator.rb +68 -0
- data/lib/soka/rails/agent_extensions.rb +42 -0
- data/lib/soka/rails/configuration.rb +65 -0
- data/lib/soka/rails/errors.rb +73 -0
- data/lib/soka/rails/railtie.rb +15 -0
- data/lib/soka/rails/rspec.rb +29 -0
- data/lib/soka/rails/test_helpers.rb +117 -0
- data/lib/soka/rails/version.rb +7 -0
- data/lib/soka/rails.rb +24 -0
- data/lib/soka_rails.rb +11 -0
- metadata +124 -0
@@ -0,0 +1,68 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'rails/generators/named_base'
|
4
|
+
|
5
|
+
module Soka
|
6
|
+
module Generators
|
7
|
+
# Generator for creating new Soka tool classes with configurable parameters
|
8
|
+
class ToolGenerator < ::Rails::Generators::NamedBase
|
9
|
+
source_root File.expand_path('templates', __dir__)
|
10
|
+
|
11
|
+
argument :params, type: :array, default: [], banner: 'param1:type param2:type'
|
12
|
+
|
13
|
+
def create_tool_file
|
14
|
+
@tool_class_name = tool_class_name
|
15
|
+
@params_list = parse_params
|
16
|
+
|
17
|
+
template 'tool.rb.tt',
|
18
|
+
File.join('app/soka/tools', class_path, "#{tool_file_name}.rb")
|
19
|
+
end
|
20
|
+
|
21
|
+
def create_test_file
|
22
|
+
return unless rspec_installed?
|
23
|
+
|
24
|
+
@tool_class_name = tool_class_name
|
25
|
+
@params_list = parse_params
|
26
|
+
|
27
|
+
template 'tool_spec.rb.tt',
|
28
|
+
File.join('spec/soka/tools', class_path, "#{tool_file_name}_spec.rb")
|
29
|
+
end
|
30
|
+
|
31
|
+
private
|
32
|
+
|
33
|
+
# Normalize the tool file name to always end with _tool
|
34
|
+
def tool_file_name
|
35
|
+
base_name = file_name.to_s
|
36
|
+
|
37
|
+
# Remove existing _tool suffix if present to avoid duplication
|
38
|
+
base_name = base_name.sub(/_tool\z/, '')
|
39
|
+
|
40
|
+
# Add _tool suffix
|
41
|
+
"#{base_name}_tool"
|
42
|
+
end
|
43
|
+
|
44
|
+
# Normalize the tool class name to always end with Tool
|
45
|
+
def tool_class_name
|
46
|
+
base_class = class_name.to_s
|
47
|
+
|
48
|
+
# Remove existing Tool suffix if present to avoid duplication
|
49
|
+
base_class = base_class.sub(/Tool\z/, '')
|
50
|
+
|
51
|
+
# Add Tool suffix
|
52
|
+
"#{base_class}Tool"
|
53
|
+
end
|
54
|
+
|
55
|
+
def parse_params
|
56
|
+
params.map do |param|
|
57
|
+
name, type = param.split(':')
|
58
|
+
{ name: name, type: type.capitalize || 'String' }
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
def rspec_installed?
|
63
|
+
File.exist?(::Rails.root.join('spec/spec_helper.rb')) ||
|
64
|
+
File.exist?(::Rails.root.join('spec/rails_helper.rb'))
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
@@ -0,0 +1,42 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Soka
|
4
|
+
module Rails
|
5
|
+
# Extensions for Soka::Agent to integrate with Rails configuration
|
6
|
+
module AgentExtensions
|
7
|
+
def self.included(base)
|
8
|
+
base.extend(ClassMethods)
|
9
|
+
end
|
10
|
+
|
11
|
+
# Class methods for agent configuration
|
12
|
+
module ClassMethods
|
13
|
+
def inherited(subclass)
|
14
|
+
super
|
15
|
+
apply_rails_configuration(subclass)
|
16
|
+
end
|
17
|
+
|
18
|
+
private
|
19
|
+
|
20
|
+
def apply_rails_configuration(subclass)
|
21
|
+
return unless defined?(Soka::Rails.configuration)
|
22
|
+
|
23
|
+
rails_config = Soka::Rails.configuration
|
24
|
+
apply_configuration_values(subclass, rails_config)
|
25
|
+
end
|
26
|
+
|
27
|
+
def apply_configuration_values(subclass, config)
|
28
|
+
return unless config
|
29
|
+
|
30
|
+
subclass.provider config.ai_provider if config.ai_provider
|
31
|
+
subclass.model config.ai_model if config.ai_model
|
32
|
+
subclass.api_key config.ai_api_key if config.ai_api_key
|
33
|
+
subclass.max_iterations config.max_iterations if config.max_iterations
|
34
|
+
subclass.timeout config.timeout if config.timeout
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
# Apply extensions to Soka::Agent
|
42
|
+
Soka::Agent.include(Soka::Rails::AgentExtensions) if defined?(Soka::Agent)
|
@@ -0,0 +1,65 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Soka
|
4
|
+
module Rails
|
5
|
+
# Main configuration class for Soka Rails settings
|
6
|
+
class Configuration
|
7
|
+
attr_accessor :ai_provider, :ai_model, :ai_api_key, :max_iterations, :timeout
|
8
|
+
|
9
|
+
def initialize
|
10
|
+
# Use ENV.fetch to set default values
|
11
|
+
@ai_provider = ENV.fetch('SOKA_PROVIDER', :gemini).to_sym
|
12
|
+
@ai_model = ENV.fetch('SOKA_MODEL', 'gemini-2.0-flash-exp')
|
13
|
+
@ai_api_key = ENV.fetch('SOKA_API_KEY', nil)
|
14
|
+
|
15
|
+
# Performance settings
|
16
|
+
@max_iterations = defined?(::Rails) && ::Rails.env.production? ? 10 : 5
|
17
|
+
@timeout = 30
|
18
|
+
end
|
19
|
+
|
20
|
+
# DSL configuration methods
|
21
|
+
def ai
|
22
|
+
yield(AIConfig.new(self)) if block_given?
|
23
|
+
end
|
24
|
+
|
25
|
+
def performance
|
26
|
+
yield(PerformanceConfig.new(self)) if block_given?
|
27
|
+
end
|
28
|
+
|
29
|
+
# Internal configuration classes
|
30
|
+
# DSL class for AI-specific configuration settings
|
31
|
+
class AIConfig
|
32
|
+
def initialize(config)
|
33
|
+
@config = config
|
34
|
+
end
|
35
|
+
|
36
|
+
def provider=(value)
|
37
|
+
@config.ai_provider = value
|
38
|
+
end
|
39
|
+
|
40
|
+
def model=(value)
|
41
|
+
@config.ai_model = value
|
42
|
+
end
|
43
|
+
|
44
|
+
def api_key=(value)
|
45
|
+
@config.ai_api_key = value
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
# DSL class for performance-related configuration settings
|
50
|
+
class PerformanceConfig
|
51
|
+
def initialize(config)
|
52
|
+
@config = config
|
53
|
+
end
|
54
|
+
|
55
|
+
def max_iterations=(value)
|
56
|
+
@config.max_iterations = value
|
57
|
+
end
|
58
|
+
|
59
|
+
def timeout=(value)
|
60
|
+
@config.timeout = value.is_a?(Numeric) ? value : value.to_i
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
@@ -0,0 +1,73 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Soka
|
4
|
+
module Rails
|
5
|
+
# Base error class for Soka Rails
|
6
|
+
class Error < StandardError; end
|
7
|
+
|
8
|
+
# Configuration related errors
|
9
|
+
# Raised when there are configuration-related issues
|
10
|
+
class ConfigurationError < Error; end
|
11
|
+
|
12
|
+
# Agent related errors
|
13
|
+
# Raised when agent execution encounters problems
|
14
|
+
class AgentError < Error; end
|
15
|
+
|
16
|
+
# Tool related errors
|
17
|
+
# Raised when tool execution or validation fails
|
18
|
+
class ToolError < Error; end
|
19
|
+
|
20
|
+
# Generator related errors
|
21
|
+
# Raised when generator operations fail
|
22
|
+
class GeneratorError < Error; end
|
23
|
+
|
24
|
+
# Specific error classes
|
25
|
+
# Raised when API key is missing for the configured provider
|
26
|
+
class MissingApiKeyError < ConfigurationError
|
27
|
+
def initialize(provider = nil)
|
28
|
+
message = if provider
|
29
|
+
"Missing API key for provider: #{provider}. " \
|
30
|
+
"Please set SOKA_API_KEY or SOKA_#{provider.to_s.upcase}_API_KEY environment variable."
|
31
|
+
else
|
32
|
+
'Missing API key. Please set SOKA_API_KEY environment variable.'
|
33
|
+
end
|
34
|
+
super(message)
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
# Raised when an unsupported AI provider is specified
|
39
|
+
class InvalidProviderError < ConfigurationError
|
40
|
+
def initialize(provider)
|
41
|
+
super("Invalid AI provider: #{provider}. Supported providers: :gemini, :openai, :anthropic")
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
# Raised when agent execution exceeds the configured timeout
|
46
|
+
class AgentTimeoutError < AgentError
|
47
|
+
def initialize(timeout)
|
48
|
+
super("Agent execution timeout after #{timeout} seconds")
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
# Raised when agent exceeds maximum allowed iterations
|
53
|
+
class MaxIterationsExceededError < AgentError
|
54
|
+
def initialize(max_iterations)
|
55
|
+
super("Agent exceeded maximum iterations limit of #{max_iterations}")
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
# Raised when a requested tool cannot be found
|
60
|
+
class ToolNotFoundError < ToolError
|
61
|
+
def initialize(tool_name)
|
62
|
+
super("Tool not found: #{tool_name}")
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
# Raised when tool is called with invalid parameters
|
67
|
+
class InvalidToolParametersError < ToolError
|
68
|
+
def initialize(tool_name, errors)
|
69
|
+
super("Invalid parameters for tool #{tool_name}: #{errors.join(', ')}")
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Soka
|
4
|
+
module Rails
|
5
|
+
# Rails integration for Soka, configuring autoloading and initializers
|
6
|
+
class Railtie < ::Rails::Railtie
|
7
|
+
# Configure autoloading - executed after Rails completes basic setup
|
8
|
+
initializer 'soka.setup_autoloading', before: :set_autoload_paths do |app|
|
9
|
+
# Add app/soka to autoload paths
|
10
|
+
# eager_load: true will automatically include all subdirectories
|
11
|
+
app.config.paths.add 'app/soka', eager_load: true
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'soka/rails/test_helpers'
|
4
|
+
|
5
|
+
if defined?(RSpec)
|
6
|
+
RSpec.configure do |config|
|
7
|
+
config.include Soka::Rails::TestHelpers, type: :agent
|
8
|
+
config.include Soka::Rails::TestHelpers, type: :tool
|
9
|
+
|
10
|
+
config.before(:each, type: :agent) do
|
11
|
+
# Reset Soka configuration
|
12
|
+
Soka.configuration = Soka::Configuration.new if defined?(Soka) && Soka.respond_to?(:configuration=)
|
13
|
+
end
|
14
|
+
|
15
|
+
config.before(:each, type: :tool) do
|
16
|
+
# Ensure Rails environment is available
|
17
|
+
allow(Rails).to receive(:env).and_return(ActiveSupport::StringInquirer.new('test')) if defined?(Rails)
|
18
|
+
end
|
19
|
+
|
20
|
+
# Automatically tag tests under spec/soka directory
|
21
|
+
config.define_derived_metadata(file_path: %r{/spec/soka/agents/}) do |metadata|
|
22
|
+
metadata[:type] = :agent
|
23
|
+
end
|
24
|
+
|
25
|
+
config.define_derived_metadata(file_path: %r{/spec/soka/tools/}) do |metadata|
|
26
|
+
metadata[:type] = :tool
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,117 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Soka
|
4
|
+
module Rails
|
5
|
+
# Test helpers for RSpec tests with Soka agents and tools
|
6
|
+
module TestHelpers
|
7
|
+
extend ActiveSupport::Concern
|
8
|
+
|
9
|
+
included do
|
10
|
+
let(:mock_llm) { instance_double('Soka::LLM') }
|
11
|
+
end
|
12
|
+
|
13
|
+
# Mock AI response
|
14
|
+
def mock_ai_response(response_attrs = {})
|
15
|
+
response = build_mock_response(response_attrs)
|
16
|
+
setup_llm_mock(response)
|
17
|
+
end
|
18
|
+
|
19
|
+
def build_mock_response(attrs)
|
20
|
+
default_response = {
|
21
|
+
final_answer: 'Mocked answer',
|
22
|
+
confidence_score: 0.95,
|
23
|
+
status: :completed,
|
24
|
+
iterations: 1,
|
25
|
+
thought_process: []
|
26
|
+
}
|
27
|
+
default_response.merge(attrs)
|
28
|
+
end
|
29
|
+
|
30
|
+
def setup_llm_mock(response)
|
31
|
+
return unless defined?(Soka::LLM)
|
32
|
+
|
33
|
+
allow(Soka::LLM).to receive(:new).and_return(mock_llm)
|
34
|
+
allow(mock_llm).to receive(:chat).and_return(
|
35
|
+
Struct.new(:content).new(build_react_response(response))
|
36
|
+
)
|
37
|
+
end
|
38
|
+
|
39
|
+
# Mock tool execution
|
40
|
+
def mock_tool_execution(tool_class, result)
|
41
|
+
allow_any_instance_of(tool_class).to receive(:call).and_return(result)
|
42
|
+
end
|
43
|
+
|
44
|
+
# Build ReAct format response
|
45
|
+
def build_react_response(attrs)
|
46
|
+
thoughts = attrs[:thought_process].presence ||
|
47
|
+
['Analyzing the request']
|
48
|
+
|
49
|
+
response = thoughts.map { |t| "<Thought>#{t}</Thought>" }.join("\n")
|
50
|
+
response += "\n<Final_Answer>#{attrs[:final_answer]}</Final_Answer>"
|
51
|
+
response
|
52
|
+
end
|
53
|
+
|
54
|
+
# Agent test helper methods
|
55
|
+
def run_agent(agent, input, &)
|
56
|
+
result = if block_given?
|
57
|
+
agent.run(input, &)
|
58
|
+
else
|
59
|
+
agent.run(input)
|
60
|
+
end
|
61
|
+
|
62
|
+
expect(result).to be_a(Struct)
|
63
|
+
result
|
64
|
+
end
|
65
|
+
|
66
|
+
# Event collector
|
67
|
+
def collect_agent_events(agent, input)
|
68
|
+
events = []
|
69
|
+
|
70
|
+
agent.run(input) do |event|
|
71
|
+
events << event
|
72
|
+
end
|
73
|
+
|
74
|
+
events
|
75
|
+
end
|
76
|
+
|
77
|
+
# Test configuration
|
78
|
+
def with_test_configuration
|
79
|
+
original_config = Soka::Rails.configuration.dup
|
80
|
+
|
81
|
+
Soka::Rails.configure do |config|
|
82
|
+
config.ai_provider = :mock
|
83
|
+
config.max_iterations = 3
|
84
|
+
config.timeout = 5
|
85
|
+
yield config if block_given?
|
86
|
+
end
|
87
|
+
|
88
|
+
yield
|
89
|
+
ensure
|
90
|
+
Soka::Rails.configuration = original_config
|
91
|
+
end
|
92
|
+
|
93
|
+
# Helper method: create successful result
|
94
|
+
def successful_result(attrs = {})
|
95
|
+
default_attrs = {
|
96
|
+
status: :completed,
|
97
|
+
final_answer: 'Success',
|
98
|
+
confidence_score: 0.95,
|
99
|
+
iterations: 1
|
100
|
+
}
|
101
|
+
|
102
|
+
Struct.new(*default_attrs.keys).new(*default_attrs.merge(attrs).values)
|
103
|
+
end
|
104
|
+
|
105
|
+
# Helper method: check if result is successful
|
106
|
+
RSpec::Matchers.define :be_successful do
|
107
|
+
match do |actual|
|
108
|
+
actual.respond_to?(:status) && actual.status == :completed
|
109
|
+
end
|
110
|
+
|
111
|
+
failure_message do |actual|
|
112
|
+
"expected result to be successful, but status was #{actual.status}"
|
113
|
+
end
|
114
|
+
end
|
115
|
+
end
|
116
|
+
end
|
117
|
+
end
|
data/lib/soka/rails.rb
ADDED
@@ -0,0 +1,24 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative 'rails/version'
|
4
|
+
require_relative 'rails/configuration'
|
5
|
+
require_relative 'rails/errors'
|
6
|
+
require_relative 'rails/railtie'
|
7
|
+
require_relative 'rails/agent_extensions'
|
8
|
+
|
9
|
+
module Soka
|
10
|
+
# Rails integration for Soka AI Agent Framework
|
11
|
+
module Rails
|
12
|
+
class << self
|
13
|
+
attr_writer :configuration
|
14
|
+
|
15
|
+
def configuration
|
16
|
+
@configuration ||= Configuration.new
|
17
|
+
end
|
18
|
+
|
19
|
+
def configure
|
20
|
+
yield(configuration)
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
data/lib/soka_rails.rb
ADDED
@@ -0,0 +1,11 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# This file serves as the entry point for the soka-rails gem
|
4
|
+
# It ensures proper loading order for Rails integration
|
5
|
+
|
6
|
+
require 'rails'
|
7
|
+
require 'soka'
|
8
|
+
require 'zeitwerk'
|
9
|
+
|
10
|
+
# Load the main Soka::Rails module
|
11
|
+
require_relative 'soka/rails'
|
metadata
ADDED
@@ -0,0 +1,124 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: soka-rails
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1.beta4
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- jiunjiun
|
8
|
+
bindir: bin
|
9
|
+
cert_chain: []
|
10
|
+
date: 1980-01-02 00:00:00.000000000 Z
|
11
|
+
dependencies:
|
12
|
+
- !ruby/object:Gem::Dependency
|
13
|
+
name: rails
|
14
|
+
requirement: !ruby/object:Gem::Requirement
|
15
|
+
requirements:
|
16
|
+
- - ">="
|
17
|
+
- !ruby/object:Gem::Version
|
18
|
+
version: '7.0'
|
19
|
+
- - "<"
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: '9.0'
|
22
|
+
type: :runtime
|
23
|
+
prerelease: false
|
24
|
+
version_requirements: !ruby/object:Gem::Requirement
|
25
|
+
requirements:
|
26
|
+
- - ">="
|
27
|
+
- !ruby/object:Gem::Version
|
28
|
+
version: '7.0'
|
29
|
+
- - "<"
|
30
|
+
- !ruby/object:Gem::Version
|
31
|
+
version: '9.0'
|
32
|
+
- !ruby/object:Gem::Dependency
|
33
|
+
name: soka
|
34
|
+
requirement: !ruby/object:Gem::Requirement
|
35
|
+
requirements:
|
36
|
+
- - "~>"
|
37
|
+
- !ruby/object:Gem::Version
|
38
|
+
version: 0.0.1
|
39
|
+
type: :runtime
|
40
|
+
prerelease: false
|
41
|
+
version_requirements: !ruby/object:Gem::Requirement
|
42
|
+
requirements:
|
43
|
+
- - "~>"
|
44
|
+
- !ruby/object:Gem::Version
|
45
|
+
version: 0.0.1
|
46
|
+
- !ruby/object:Gem::Dependency
|
47
|
+
name: zeitwerk
|
48
|
+
requirement: !ruby/object:Gem::Requirement
|
49
|
+
requirements:
|
50
|
+
- - "~>"
|
51
|
+
- !ruby/object:Gem::Version
|
52
|
+
version: '2.6'
|
53
|
+
type: :runtime
|
54
|
+
prerelease: false
|
55
|
+
version_requirements: !ruby/object:Gem::Requirement
|
56
|
+
requirements:
|
57
|
+
- - "~>"
|
58
|
+
- !ruby/object:Gem::Version
|
59
|
+
version: '2.6'
|
60
|
+
description: Soka Rails provides seamless integration between the Soka AI Agent Framework
|
61
|
+
and Ruby on Rails applications, following Rails conventions for easy adoption.
|
62
|
+
email:
|
63
|
+
- imjiunjiun@gmail.com
|
64
|
+
executables: []
|
65
|
+
extensions: []
|
66
|
+
extra_rdoc_files: []
|
67
|
+
files:
|
68
|
+
- ".rspec"
|
69
|
+
- ".rubocop.yml"
|
70
|
+
- CHANGELOG.md
|
71
|
+
- CLAUDE.md
|
72
|
+
- DESIGN.md
|
73
|
+
- LICENSE
|
74
|
+
- README.md
|
75
|
+
- REQUIREMENT.md
|
76
|
+
- Rakefile
|
77
|
+
- SPEC.md
|
78
|
+
- app/soka/agents/application_agent.rb
|
79
|
+
- app/soka/tools/application_tool.rb
|
80
|
+
- lib/generators/soka/agent/agent_generator.rb
|
81
|
+
- lib/generators/soka/agent/templates/agent.rb.tt
|
82
|
+
- lib/generators/soka/agent/templates/agent_spec.rb.tt
|
83
|
+
- lib/generators/soka/install/install_generator.rb
|
84
|
+
- lib/generators/soka/install/templates/application_agent.rb
|
85
|
+
- lib/generators/soka/install/templates/application_tool.rb
|
86
|
+
- lib/generators/soka/install/templates/soka.rb
|
87
|
+
- lib/generators/soka/tool/templates/tool.rb.tt
|
88
|
+
- lib/generators/soka/tool/templates/tool_spec.rb.tt
|
89
|
+
- lib/generators/soka/tool/tool_generator.rb
|
90
|
+
- lib/soka/rails.rb
|
91
|
+
- lib/soka/rails/agent_extensions.rb
|
92
|
+
- lib/soka/rails/configuration.rb
|
93
|
+
- lib/soka/rails/errors.rb
|
94
|
+
- lib/soka/rails/railtie.rb
|
95
|
+
- lib/soka/rails/rspec.rb
|
96
|
+
- lib/soka/rails/test_helpers.rb
|
97
|
+
- lib/soka/rails/version.rb
|
98
|
+
- lib/soka_rails.rb
|
99
|
+
homepage: https://github.com/jiunjiun/soka-rails
|
100
|
+
licenses:
|
101
|
+
- MIT
|
102
|
+
metadata:
|
103
|
+
homepage_uri: https://github.com/jiunjiun/soka-rails
|
104
|
+
source_code_uri: https://github.com/jiunjiun/soka-rails
|
105
|
+
changelog_uri: https://github.com/jiunjiun/soka-rails/blob/main/CHANGELOG.md
|
106
|
+
rubygems_mfa_required: 'true'
|
107
|
+
rdoc_options: []
|
108
|
+
require_paths:
|
109
|
+
- lib
|
110
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
111
|
+
requirements:
|
112
|
+
- - ">="
|
113
|
+
- !ruby/object:Gem::Version
|
114
|
+
version: '3.4'
|
115
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
116
|
+
requirements:
|
117
|
+
- - ">="
|
118
|
+
- !ruby/object:Gem::Version
|
119
|
+
version: '0'
|
120
|
+
requirements: []
|
121
|
+
rubygems_version: 3.6.9
|
122
|
+
specification_version: 4
|
123
|
+
summary: Rails integration for Soka AI Agent Framework
|
124
|
+
test_files: []
|