omni_agent 0.1.4 → 0.1.5
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 +4 -4
- data/CHANGELOG.md +28 -18
- data/lib/generators/omni_agent/agent/agent_generator.rb +1 -1
- data/lib/omni_agent/agent.rb +18 -1
- data/lib/omni_agent/configuration.rb +4 -1
- data/lib/omni_agent/errors.rb +4 -0
- data/lib/omni_agent/providers/base.rb +23 -0
- data/lib/omni_agent/providers/openai.rb +8 -1
- data/lib/omni_agent/version.rb +1 -1
- data/lib/omni_agent.rb +6 -0
- metadata +3 -6
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 1513c46e356438c23dfd193f25c390df240f2d1d812813114e2e582222de2965
|
|
4
|
+
data.tar.gz: a9b05b4445128aea795b3f7f5ea80cb6bd668bf2b674c15651011ce6780e0c2e
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 4ee226683fb316a82a18457b50bbe783712fe4ad9115befa4ab7c9421b31747acf2b3f609360c126a599ac8dded16a9cc4dda670e115f3bed3711147776956a3
|
|
7
|
+
data.tar.gz: 6ab849bcae377ccc919d6daf13b0556d9d6ed07b1cd16d645fe66fb026df4dd941d4f9a06b396ea044bb4ad0db886457c25ce1ca4a4c4d4de6306dc31edf47f2
|
data/CHANGELOG.md
CHANGED
|
@@ -4,25 +4,27 @@ All notable changes to this project will be documented in this file.
|
|
|
4
4
|
|
|
5
5
|
## [Unreleased]
|
|
6
6
|
|
|
7
|
-
## [0.1.
|
|
7
|
+
## [0.1.5] - 2026-06-18
|
|
8
8
|
|
|
9
9
|
### Added
|
|
10
|
-
-
|
|
11
|
-
-
|
|
12
|
-
- OpenAI provider support via the `openai` gem.
|
|
13
|
-
- Tool DSL with JSON schema generation.
|
|
14
|
-
- Rails generators and tasks for agent scaffolding.
|
|
15
|
-
- RSpec coverage for agent runtime, providers, tools, and integration flows.
|
|
10
|
+
- Added max tool iterations limit on the agent loop, with corresponding error raised when exceeded.
|
|
11
|
+
- Added retry logic to the OpenAI provider, configurable via `Configuration`.
|
|
16
12
|
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
- Lowered Rails version needed.
|
|
13
|
+
### Fixed
|
|
14
|
+
- Improved provider resolution error handling for unknown providers.
|
|
15
|
+
- Forced eager load of error aliases to avoid Zeitwerk autoloading issues.
|
|
21
16
|
|
|
22
|
-
|
|
17
|
+
# [0.1.4] - 2026-06-16
|
|
23
18
|
|
|
24
19
|
### Fixed
|
|
25
|
-
-
|
|
20
|
+
- Change invoke method to an instance method instead of a class method, to actually catch invocations of the `stop_generation!` method.
|
|
21
|
+
|
|
22
|
+
### Changed
|
|
23
|
+
- Remove agent file from directory to prevent needing to change Zeitwerk initializer as Railtie wasn't allowing to change behaviour without it.
|
|
24
|
+
|
|
25
|
+
### Added
|
|
26
|
+
- Add Railtie to project to handle concerns.
|
|
27
|
+
- Added docusaurus, the actual docs will be done later.
|
|
26
28
|
|
|
27
29
|
## [0.1.3] - 2026-06-12
|
|
28
30
|
|
|
@@ -36,14 +38,22 @@ All notable changes to this project will be documented in this file.
|
|
|
36
38
|
- Added `history` as a context variable which are the messages to be sent to the provider.
|
|
37
39
|
- Added support for nested datatypes in the `array` schema for tools
|
|
38
40
|
|
|
39
|
-
|
|
41
|
+
## [0.1.2] - 2026-06-11
|
|
40
42
|
|
|
41
43
|
### Fixed
|
|
42
|
-
-
|
|
44
|
+
- Fixed Zeitwerk issue with `OmniAgent::Errors`
|
|
45
|
+
|
|
46
|
+
## [0.1.1] - 2026-06-09
|
|
43
47
|
|
|
44
48
|
### Changed
|
|
45
|
-
-
|
|
49
|
+
- Lowered Rails version needed.
|
|
50
|
+
|
|
51
|
+
## [0.1.0] - 2026-06-09
|
|
46
52
|
|
|
47
53
|
### Added
|
|
48
|
-
-
|
|
49
|
-
-
|
|
54
|
+
- Initial release of OmniAgent as a Rails engine for building application-native AI agents.
|
|
55
|
+
- Agent runtime with provider abstraction, tool-calling loop, callbacks, and prompt rendering.
|
|
56
|
+
- OpenAI provider support via the `openai` gem.
|
|
57
|
+
- Tool DSL with JSON schema generation.
|
|
58
|
+
- Rails generators and tasks for agent scaffolding.
|
|
59
|
+
- RSpec coverage for agent runtime, providers, tools, and integration flows.
|
data/lib/omni_agent/agent.rb
CHANGED
|
@@ -159,8 +159,17 @@ module OmniAgent
|
|
|
159
159
|
initial_messages_count = messages.length - 1
|
|
160
160
|
|
|
161
161
|
filtered_tools = tool_filter(tools: available_tools, agent_tags: self.class.tags)
|
|
162
|
+
max_iterations = OmniAgent.configuration.max_tool_iterations
|
|
163
|
+
iterations = 0
|
|
162
164
|
|
|
163
165
|
loop do
|
|
166
|
+
iterations += 1
|
|
167
|
+
if iterations > max_iterations
|
|
168
|
+
raise OmniAgent::MaxToolIterationsError,
|
|
169
|
+
"Exceeded max_tool_iterations (#{max_iterations}) without a final response. " \
|
|
170
|
+
"Increase OmniAgent.configuration.max_tool_iterations if more tool calls are expected."
|
|
171
|
+
end
|
|
172
|
+
|
|
164
173
|
response = provider.chat(messages: messages, tools: filtered_tools, **@chat_options)
|
|
165
174
|
|
|
166
175
|
if response.content && !response.tool_calls?
|
|
@@ -309,7 +318,15 @@ module OmniAgent
|
|
|
309
318
|
end
|
|
310
319
|
|
|
311
320
|
def resolve_provider(name, model)
|
|
312
|
-
OmniAgent::Providers.registry[name.to_sym]
|
|
321
|
+
provider_class = OmniAgent::Providers.registry[name.to_sym]
|
|
322
|
+
|
|
323
|
+
unless provider_class
|
|
324
|
+
known = OmniAgent::Providers.registry.keys.join(", ")
|
|
325
|
+
raise OmniAgent::UnknownProviderError,
|
|
326
|
+
"Unknown provider #{name.inspect}. Known providers: #{known}"
|
|
327
|
+
end
|
|
328
|
+
|
|
329
|
+
provider_class.new(model: model)
|
|
313
330
|
end
|
|
314
331
|
|
|
315
332
|
def run_before_generation_callbacks(input:, context:, messages:)
|
|
@@ -1,10 +1,13 @@
|
|
|
1
1
|
module OmniAgent
|
|
2
2
|
class Configuration
|
|
3
|
-
attr_accessor :default_provider, :default_model
|
|
3
|
+
attr_accessor :default_provider, :default_model, :max_retries, :retry_base_delay, :max_tool_iterations
|
|
4
4
|
|
|
5
5
|
def initialize
|
|
6
6
|
@default_provider = :openai
|
|
7
7
|
@default_model = "gpt-4o-mini"
|
|
8
|
+
@max_retries = 3
|
|
9
|
+
@retry_base_delay = 0.5
|
|
10
|
+
@max_tool_iterations = 10
|
|
8
11
|
end
|
|
9
12
|
end
|
|
10
13
|
end
|
data/lib/omni_agent/errors.rb
CHANGED
|
@@ -2,8 +2,12 @@ module OmniAgent
|
|
|
2
2
|
module Errors
|
|
3
3
|
class Error < StandardError; end
|
|
4
4
|
class MissingDependencyError < Error; end
|
|
5
|
+
class UnknownProviderError < Error; end
|
|
6
|
+
class MaxToolIterationsError < Error; end
|
|
5
7
|
end
|
|
6
8
|
|
|
7
9
|
Error = Errors::Error
|
|
8
10
|
MissingDependencyError = Errors::MissingDependencyError
|
|
11
|
+
UnknownProviderError = Errors::UnknownProviderError
|
|
12
|
+
MaxToolIterationsError = Errors::MaxToolIterationsError
|
|
9
13
|
end
|
|
@@ -49,6 +49,29 @@ module OmniAgent
|
|
|
49
49
|
raise NotImplementedError, "Providers must define a default model"
|
|
50
50
|
end
|
|
51
51
|
|
|
52
|
+
# Override in subclasses to flag exceptions worth retrying (rate limits, timeouts, 5xx).
|
|
53
|
+
def retryable_error?(_error)
|
|
54
|
+
false
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
def with_retries
|
|
58
|
+
max_retries = OmniAgent.configuration.max_retries
|
|
59
|
+
base_delay = OmniAgent.configuration.retry_base_delay
|
|
60
|
+
attempt = 0
|
|
61
|
+
|
|
62
|
+
begin
|
|
63
|
+
yield
|
|
64
|
+
rescue => e
|
|
65
|
+
raise unless retryable_error?(e)
|
|
66
|
+
|
|
67
|
+
attempt += 1
|
|
68
|
+
raise if attempt > max_retries
|
|
69
|
+
|
|
70
|
+
sleep(base_delay * (2**(attempt - 1)))
|
|
71
|
+
retry
|
|
72
|
+
end
|
|
73
|
+
end
|
|
74
|
+
|
|
52
75
|
def validate_message_payload!(message, index, role_name)
|
|
53
76
|
has_content = message.key?(:content) || message.key?("content")
|
|
54
77
|
content_value = message[:content] || message["content"]
|
|
@@ -44,7 +44,7 @@ module OmniAgent
|
|
|
44
44
|
payload[:tools] = openai_tools if openai_tools.any?
|
|
45
45
|
payload.merge!(options) if options.any?
|
|
46
46
|
|
|
47
|
-
response = client.chat.completions.create(**payload)
|
|
47
|
+
response = with_retries { client.chat.completions.create(**payload) }
|
|
48
48
|
|
|
49
49
|
parse_response(response, payload)
|
|
50
50
|
rescue => e
|
|
@@ -53,6 +53,13 @@ module OmniAgent
|
|
|
53
53
|
|
|
54
54
|
protected
|
|
55
55
|
|
|
56
|
+
def retryable_error?(error)
|
|
57
|
+
defined?(::OpenAI::Errors) &&
|
|
58
|
+
(error.is_a?(::OpenAI::Errors::RateLimitError) ||
|
|
59
|
+
error.is_a?(::OpenAI::Errors::InternalServerError) ||
|
|
60
|
+
error.is_a?(::OpenAI::Errors::APIConnectionError))
|
|
61
|
+
end
|
|
62
|
+
|
|
56
63
|
def client
|
|
57
64
|
@client ||= ::OpenAI::Client.new(api_key: @api_key)
|
|
58
65
|
end
|
data/lib/omni_agent/version.rb
CHANGED
data/lib/omni_agent.rb
CHANGED
|
@@ -7,6 +7,12 @@ loader.inflector.inflect("openai" => "OpenAI")
|
|
|
7
7
|
loader.ignore(File.expand_path("generators", __dir__))
|
|
8
8
|
loader.setup
|
|
9
9
|
|
|
10
|
+
# errors.rb defines top-level aliases (OmniAgent::MissingDependencyError, etc.)
|
|
11
|
+
# that Zeitwerk cannot autoload, since they don't map to a file path of their
|
|
12
|
+
# own. Force it to load eagerly so the aliases exist regardless of which
|
|
13
|
+
# constant is referenced first.
|
|
14
|
+
require "omni_agent/errors"
|
|
15
|
+
|
|
10
16
|
|
|
11
17
|
module OmniAgent
|
|
12
18
|
class << self
|
metadata
CHANGED
|
@@ -1,14 +1,13 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: omni_agent
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.1.
|
|
4
|
+
version: 0.1.5
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- ACR1209
|
|
8
|
-
autorequire:
|
|
9
8
|
bindir: bin
|
|
10
9
|
cert_chain: []
|
|
11
|
-
date:
|
|
10
|
+
date: 1980-01-02 00:00:00.000000000 Z
|
|
12
11
|
dependencies:
|
|
13
12
|
- !ruby/object:Gem::Dependency
|
|
14
13
|
name: rails
|
|
@@ -82,7 +81,6 @@ metadata:
|
|
|
82
81
|
homepage_uri: https://github.com/ACR1209/omni_agent
|
|
83
82
|
source_code_uri: https://github.com/ACR1209/omni_agent
|
|
84
83
|
changelog_uri: https://github.com/ACR1209/omni_agent/blob/main/CHANGELOG.md
|
|
85
|
-
post_install_message:
|
|
86
84
|
rdoc_options: []
|
|
87
85
|
require_paths:
|
|
88
86
|
- lib
|
|
@@ -97,8 +95,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
97
95
|
- !ruby/object:Gem::Version
|
|
98
96
|
version: '0'
|
|
99
97
|
requirements: []
|
|
100
|
-
rubygems_version: 3.
|
|
101
|
-
signing_key:
|
|
98
|
+
rubygems_version: 3.6.9
|
|
102
99
|
specification_version: 4
|
|
103
100
|
summary: Rails engine for building AI agents with tools.
|
|
104
101
|
test_files: []
|