activeagent 0.6.3 → 1.0.0.rc1
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 +210 -2
- data/README.md +15 -24
- data/lib/active_agent/base.rb +389 -39
- data/lib/active_agent/concerns/callbacks.rb +251 -0
- data/lib/active_agent/concerns/observers.rb +147 -0
- data/lib/active_agent/concerns/parameterized.rb +292 -0
- data/lib/active_agent/concerns/provider.rb +120 -0
- data/lib/active_agent/concerns/queueing.rb +36 -0
- data/lib/active_agent/concerns/rescue.rb +64 -0
- data/lib/active_agent/concerns/streaming.rb +282 -0
- data/lib/active_agent/concerns/tooling.rb +23 -0
- data/lib/active_agent/concerns/view.rb +150 -0
- data/lib/active_agent/configuration.rb +442 -20
- data/lib/active_agent/generation.rb +141 -47
- data/lib/active_agent/generation_provider/open_router/types.rb +505 -0
- data/lib/active_agent/generation_provider/xai_provider.rb +144 -0
- data/lib/active_agent/providers/_base_provider.rb +410 -0
- data/lib/active_agent/providers/anthropic/_types.rb +63 -0
- data/lib/active_agent/providers/anthropic/options.rb +53 -0
- data/lib/active_agent/providers/anthropic/request.rb +109 -0
- data/lib/active_agent/providers/anthropic/requests/_types.rb +190 -0
- data/lib/active_agent/providers/anthropic/requests/container_params.rb +19 -0
- data/lib/active_agent/providers/anthropic/requests/content/base.rb +21 -0
- data/lib/active_agent/providers/anthropic/requests/content/sources/base.rb +22 -0
- data/lib/active_agent/providers/anthropic/requests/context_management_config.rb +18 -0
- data/lib/active_agent/providers/anthropic/requests/messages/_types.rb +189 -0
- data/lib/active_agent/providers/anthropic/requests/messages/assistant.rb +23 -0
- data/lib/active_agent/providers/anthropic/requests/messages/base.rb +63 -0
- data/lib/active_agent/providers/anthropic/requests/messages/content/_types.rb +143 -0
- data/lib/active_agent/providers/anthropic/requests/messages/content/base.rb +21 -0
- data/lib/active_agent/providers/anthropic/requests/messages/content/document.rb +26 -0
- data/lib/active_agent/providers/anthropic/requests/messages/content/image.rb +23 -0
- data/lib/active_agent/providers/anthropic/requests/messages/content/redacted_thinking.rb +21 -0
- data/lib/active_agent/providers/anthropic/requests/messages/content/search_result.rb +27 -0
- data/lib/active_agent/providers/anthropic/requests/messages/content/sources/_types.rb +171 -0
- data/lib/active_agent/providers/anthropic/requests/messages/content/sources/base.rb +22 -0
- data/lib/active_agent/providers/anthropic/requests/messages/content/sources/document_base64.rb +25 -0
- data/lib/active_agent/providers/anthropic/requests/messages/content/sources/document_file.rb +23 -0
- data/lib/active_agent/providers/anthropic/requests/messages/content/sources/document_text.rb +25 -0
- data/lib/active_agent/providers/anthropic/requests/messages/content/sources/document_url.rb +23 -0
- data/lib/active_agent/providers/anthropic/requests/messages/content/sources/image_base64.rb +27 -0
- data/lib/active_agent/providers/anthropic/requests/messages/content/sources/image_file.rb +23 -0
- data/lib/active_agent/providers/anthropic/requests/messages/content/sources/image_url.rb +23 -0
- data/lib/active_agent/providers/anthropic/requests/messages/content/text.rb +22 -0
- data/lib/active_agent/providers/anthropic/requests/messages/content/thinking.rb +23 -0
- data/lib/active_agent/providers/anthropic/requests/messages/content/tool_result.rb +24 -0
- data/lib/active_agent/providers/anthropic/requests/messages/content/tool_use.rb +28 -0
- data/lib/active_agent/providers/anthropic/requests/messages/user.rb +21 -0
- data/lib/active_agent/providers/anthropic/requests/metadata.rb +18 -0
- data/lib/active_agent/providers/anthropic/requests/response_format.rb +22 -0
- data/lib/active_agent/providers/anthropic/requests/thinking_config/_types.rb +60 -0
- data/lib/active_agent/providers/anthropic/requests/thinking_config/base.rb +20 -0
- data/lib/active_agent/providers/anthropic/requests/thinking_config/disabled.rb +16 -0
- data/lib/active_agent/providers/anthropic/requests/thinking_config/enabled.rb +20 -0
- data/lib/active_agent/providers/anthropic/requests/tool_choice/_types.rb +78 -0
- data/lib/active_agent/providers/anthropic/requests/tool_choice/any.rb +17 -0
- data/lib/active_agent/providers/anthropic/requests/tool_choice/auto.rb +17 -0
- data/lib/active_agent/providers/anthropic/requests/tool_choice/base.rb +20 -0
- data/lib/active_agent/providers/anthropic/requests/tool_choice/none.rb +16 -0
- data/lib/active_agent/providers/anthropic/requests/tool_choice/tool.rb +20 -0
- data/lib/active_agent/providers/anthropic_provider.rb +211 -0
- data/lib/active_agent/providers/common/messages/_types.rb +124 -0
- data/lib/active_agent/providers/common/messages/assistant.rb +57 -0
- data/lib/active_agent/providers/common/messages/base.rb +17 -0
- data/lib/active_agent/providers/common/messages/system.rb +20 -0
- data/lib/active_agent/providers/common/messages/tool.rb +21 -0
- data/lib/active_agent/providers/common/messages/user.rb +20 -0
- data/lib/active_agent/providers/common/model.rb +361 -0
- data/lib/active_agent/providers/common/response.rb +13 -0
- data/lib/active_agent/providers/common/responses/_types.rb +51 -0
- data/lib/active_agent/providers/common/responses/base.rb +151 -0
- data/lib/active_agent/providers/common/responses/embed.rb +33 -0
- data/lib/active_agent/providers/common/responses/format.rb +31 -0
- data/lib/active_agent/providers/common/responses/message.rb +3 -0
- data/lib/active_agent/providers/common/responses/prompt.rb +42 -0
- data/lib/active_agent/providers/concerns/exception_handler.rb +72 -0
- data/lib/active_agent/providers/concerns/previewable.rb +150 -0
- data/lib/active_agent/providers/log_subscriber.rb +360 -0
- data/lib/active_agent/providers/mock/_types.rb +77 -0
- data/lib/active_agent/providers/mock/embedding_request.rb +17 -0
- data/lib/active_agent/providers/mock/messages/_types.rb +103 -0
- data/lib/active_agent/providers/mock/messages/assistant.rb +26 -0
- data/lib/active_agent/providers/mock/messages/base.rb +63 -0
- data/lib/active_agent/providers/mock/messages/user.rb +18 -0
- data/lib/active_agent/providers/mock/options.rb +30 -0
- data/lib/active_agent/providers/mock/request.rb +38 -0
- data/lib/active_agent/providers/mock_provider.rb +311 -0
- data/lib/active_agent/providers/ollama/_types.rb +5 -0
- data/lib/active_agent/providers/ollama/chat/_types.rb +44 -0
- data/lib/active_agent/providers/ollama/chat/request.rb +70 -0
- data/lib/active_agent/providers/ollama/chat/requests/_types.rb +3 -0
- data/lib/active_agent/providers/ollama/chat/requests/messages/_types.rb +116 -0
- data/lib/active_agent/providers/ollama/chat/requests/messages/assistant.rb +19 -0
- data/lib/active_agent/providers/ollama/chat/requests/messages/user.rb +19 -0
- data/lib/active_agent/providers/ollama/embedding/_types.rb +44 -0
- data/lib/active_agent/providers/ollama/embedding/request.rb +77 -0
- data/lib/active_agent/providers/ollama/embedding/requests/_types.rb +83 -0
- data/lib/active_agent/providers/ollama/embedding/requests/options.rb +104 -0
- data/lib/active_agent/providers/ollama/options.rb +27 -0
- data/lib/active_agent/providers/ollama_provider.rb +95 -0
- data/lib/active_agent/providers/open_ai/_base.rb +58 -0
- data/lib/active_agent/providers/open_ai/_types.rb +5 -0
- data/lib/active_agent/providers/open_ai/chat/_types.rb +44 -0
- data/lib/active_agent/providers/open_ai/chat/request.rb +215 -0
- data/lib/active_agent/providers/open_ai/chat/requests/_types.rb +229 -0
- data/lib/active_agent/providers/open_ai/chat/requests/audio.rb +24 -0
- data/lib/active_agent/providers/open_ai/chat/requests/messages/_types.rb +123 -0
- data/lib/active_agent/providers/open_ai/chat/requests/messages/assistant.rb +42 -0
- data/lib/active_agent/providers/open_ai/chat/requests/messages/base.rb +78 -0
- data/lib/active_agent/providers/open_ai/chat/requests/messages/content/_types.rb +133 -0
- data/lib/active_agent/providers/open_ai/chat/requests/messages/content/audio.rb +35 -0
- data/lib/active_agent/providers/open_ai/chat/requests/messages/content/base.rb +24 -0
- data/lib/active_agent/providers/open_ai/chat/requests/messages/content/file.rb +26 -0
- data/lib/active_agent/providers/open_ai/chat/requests/messages/content/files/_types.rb +60 -0
- data/lib/active_agent/providers/open_ai/chat/requests/messages/content/files/details.rb +41 -0
- data/lib/active_agent/providers/open_ai/chat/requests/messages/content/image.rb +37 -0
- data/lib/active_agent/providers/open_ai/chat/requests/messages/content/refusal.rb +25 -0
- data/lib/active_agent/providers/open_ai/chat/requests/messages/content/text.rb +25 -0
- data/lib/active_agent/providers/open_ai/chat/requests/messages/developer.rb +25 -0
- data/lib/active_agent/providers/open_ai/chat/requests/messages/function.rb +25 -0
- data/lib/active_agent/providers/open_ai/chat/requests/messages/system.rb +25 -0
- data/lib/active_agent/providers/open_ai/chat/requests/messages/tool.rb +26 -0
- data/lib/active_agent/providers/open_ai/chat/requests/messages/user.rb +32 -0
- data/lib/active_agent/providers/open_ai/chat/requests/prediction.rb +46 -0
- data/lib/active_agent/providers/open_ai/chat/requests/response_format.rb +53 -0
- data/lib/active_agent/providers/open_ai/chat/requests/stream_options.rb +24 -0
- data/lib/active_agent/providers/open_ai/chat/requests/tool_choice.rb +26 -0
- data/lib/active_agent/providers/open_ai/chat/requests/tools/_types.rb +5 -0
- data/lib/active_agent/providers/open_ai/chat/requests/tools/base.rb +22 -0
- data/lib/active_agent/providers/open_ai/chat/requests/tools/custom_tool.rb +41 -0
- data/lib/active_agent/providers/open_ai/chat/requests/tools/function_tool.rb +51 -0
- data/lib/active_agent/providers/open_ai/chat/requests/web_search_options.rb +45 -0
- data/lib/active_agent/providers/open_ai/chat_provider.rb +198 -0
- data/lib/active_agent/providers/open_ai/embedding/_types.rb +45 -0
- data/lib/active_agent/providers/open_ai/embedding/request.rb +85 -0
- data/lib/active_agent/providers/open_ai/embedding/requests/_types.rb +49 -0
- data/lib/active_agent/providers/open_ai/options.rb +74 -0
- data/lib/active_agent/providers/open_ai/responses/_types.rb +50 -0
- data/lib/active_agent/providers/open_ai/responses/request.rb +163 -0
- data/lib/active_agent/providers/open_ai/responses/requests/_types.rb +231 -0
- data/lib/active_agent/providers/open_ai/responses/requests/conversation.rb +23 -0
- data/lib/active_agent/providers/open_ai/responses/requests/inputs/_types.rb +264 -0
- data/lib/active_agent/providers/open_ai/responses/requests/inputs/assistant_message.rb +22 -0
- data/lib/active_agent/providers/open_ai/responses/requests/inputs/base.rb +89 -0
- data/lib/active_agent/providers/open_ai/responses/requests/inputs/code_interpreter_tool_call.rb +30 -0
- data/lib/active_agent/providers/open_ai/responses/requests/inputs/computer_tool_call.rb +28 -0
- data/lib/active_agent/providers/open_ai/responses/requests/inputs/computer_tool_call_output.rb +33 -0
- data/lib/active_agent/providers/open_ai/responses/requests/inputs/content/_types.rb +207 -0
- data/lib/active_agent/providers/open_ai/responses/requests/inputs/content/base.rb +22 -0
- data/lib/active_agent/providers/open_ai/responses/requests/inputs/content/input_audio.rb +26 -0
- data/lib/active_agent/providers/open_ai/responses/requests/inputs/content/input_file.rb +28 -0
- data/lib/active_agent/providers/open_ai/responses/requests/inputs/content/input_image.rb +28 -0
- data/lib/active_agent/providers/open_ai/responses/requests/inputs/content/input_text.rb +25 -0
- data/lib/active_agent/providers/open_ai/responses/requests/inputs/custom_tool_call.rb +28 -0
- data/lib/active_agent/providers/open_ai/responses/requests/inputs/custom_tool_call_output.rb +27 -0
- data/lib/active_agent/providers/open_ai/responses/requests/inputs/developer_message.rb +20 -0
- data/lib/active_agent/providers/open_ai/responses/requests/inputs/file_search_tool_call.rb +25 -0
- data/lib/active_agent/providers/open_ai/responses/requests/inputs/function_call_output.rb +32 -0
- data/lib/active_agent/providers/open_ai/responses/requests/inputs/function_tool_call.rb +28 -0
- data/lib/active_agent/providers/open_ai/responses/requests/inputs/image_gen_tool_call.rb +27 -0
- data/lib/active_agent/providers/open_ai/responses/requests/inputs/input_message.rb +31 -0
- data/lib/active_agent/providers/open_ai/responses/requests/inputs/item_reference.rb +23 -0
- data/lib/active_agent/providers/open_ai/responses/requests/inputs/local_shell_tool_call.rb +26 -0
- data/lib/active_agent/providers/open_ai/responses/requests/inputs/local_shell_tool_call_output.rb +33 -0
- data/lib/active_agent/providers/open_ai/responses/requests/inputs/mcp_approval_request.rb +30 -0
- data/lib/active_agent/providers/open_ai/responses/requests/inputs/mcp_approval_response.rb +28 -0
- data/lib/active_agent/providers/open_ai/responses/requests/inputs/mcp_list_tools.rb +29 -0
- data/lib/active_agent/providers/open_ai/responses/requests/inputs/mcp_tool_call.rb +35 -0
- data/lib/active_agent/providers/open_ai/responses/requests/inputs/output_message.rb +35 -0
- data/lib/active_agent/providers/open_ai/responses/requests/inputs/reasoning.rb +33 -0
- data/lib/active_agent/providers/open_ai/responses/requests/inputs/system_message.rb +20 -0
- data/lib/active_agent/providers/open_ai/responses/requests/inputs/tool_call_base.rb +27 -0
- data/lib/active_agent/providers/open_ai/responses/requests/inputs/tool_message.rb +23 -0
- data/lib/active_agent/providers/open_ai/responses/requests/inputs/user_message.rb +20 -0
- data/lib/active_agent/providers/open_ai/responses/requests/inputs/web_search_tool_call.rb +24 -0
- data/lib/active_agent/providers/open_ai/responses/requests/prompt_reference.rb +23 -0
- data/lib/active_agent/providers/open_ai/responses/requests/reasoning.rb +23 -0
- data/lib/active_agent/providers/open_ai/responses/requests/stream_options.rb +20 -0
- data/lib/active_agent/providers/open_ai/responses/requests/text/_types.rb +89 -0
- data/lib/active_agent/providers/open_ai/responses/requests/text/base.rb +22 -0
- data/lib/active_agent/providers/open_ai/responses/requests/text/json_object.rb +20 -0
- data/lib/active_agent/providers/open_ai/responses/requests/text/json_schema.rb +48 -0
- data/lib/active_agent/providers/open_ai/responses/requests/text/plain.rb +20 -0
- data/lib/active_agent/providers/open_ai/responses/requests/text.rb +41 -0
- data/lib/active_agent/providers/open_ai/responses/requests/tool_choice.rb +26 -0
- data/lib/active_agent/providers/open_ai/responses/requests/tools/_types.rb +112 -0
- data/lib/active_agent/providers/open_ai/responses/requests/tools/base.rb +25 -0
- data/lib/active_agent/providers/open_ai/responses/requests/tools/code_interpreter_tool.rb +23 -0
- data/lib/active_agent/providers/open_ai/responses/requests/tools/computer_tool.rb +27 -0
- data/lib/active_agent/providers/open_ai/responses/requests/tools/custom_tool.rb +28 -0
- data/lib/active_agent/providers/open_ai/responses/requests/tools/file_search_tool.rb +27 -0
- data/lib/active_agent/providers/open_ai/responses/requests/tools/function_tool.rb +29 -0
- data/lib/active_agent/providers/open_ai/responses/requests/tools/image_generation_tool.rb +37 -0
- data/lib/active_agent/providers/open_ai/responses/requests/tools/local_shell_tool.rb +21 -0
- data/lib/active_agent/providers/open_ai/responses/requests/tools/mcp_tool.rb +41 -0
- data/lib/active_agent/providers/open_ai/responses/requests/tools/web_search_preview_tool.rb +24 -0
- data/lib/active_agent/providers/open_ai/responses/requests/tools/web_search_tool.rb +25 -0
- data/lib/active_agent/providers/open_ai/responses_provider.rb +153 -0
- data/lib/active_agent/providers/open_ai/schema.yml +65937 -0
- data/lib/active_agent/providers/open_ai_provider.rb +97 -0
- data/lib/active_agent/providers/open_router/_types.rb +45 -0
- data/lib/active_agent/providers/open_router/options.rb +93 -0
- data/lib/active_agent/providers/open_router/request.rb +83 -0
- data/lib/active_agent/providers/open_router/requests/_types.rb +198 -0
- data/lib/active_agent/providers/open_router/requests/message.rb +1 -0
- data/lib/active_agent/providers/open_router/requests/messages/_types.rb +59 -0
- data/lib/active_agent/providers/open_router/requests/messages/assistant.rb +20 -0
- data/lib/active_agent/providers/open_router/requests/messages/content/_types.rb +97 -0
- data/lib/active_agent/providers/open_router/requests/messages/content/file.rb +27 -0
- data/lib/active_agent/providers/open_router/requests/messages/content/files/_types.rb +61 -0
- data/lib/active_agent/providers/open_router/requests/messages/content/files/details.rb +26 -0
- data/lib/active_agent/providers/open_router/requests/messages/user.rb +30 -0
- data/lib/active_agent/providers/open_router/requests/plugin.rb +25 -0
- data/lib/active_agent/providers/open_router/requests/plugins/_types.rb +46 -0
- data/lib/active_agent/providers/open_router/requests/plugins/pdf_config.rb +29 -0
- data/lib/active_agent/providers/open_router/requests/prediction.rb +17 -0
- data/lib/active_agent/providers/open_router/requests/provider_preferences/_types.rb +44 -0
- data/lib/active_agent/providers/open_router/requests/provider_preferences/max_price.rb +30 -0
- data/lib/active_agent/providers/open_router/requests/provider_preferences.rb +64 -0
- data/lib/active_agent/providers/open_router/requests/response_format.rb +49 -0
- data/lib/active_agent/providers/open_router_provider.rb +53 -0
- data/lib/active_agent/providers/openai_provider.rb +2 -0
- data/lib/active_agent/providers/openrouter_provider.rb +2 -0
- data/lib/active_agent/railtie.rb +8 -6
- data/lib/active_agent/schema_generator.rb +333 -166
- data/lib/active_agent/version.rb +1 -1
- data/lib/active_agent.rb +112 -36
- data/lib/generators/active_agent/agent/USAGE +78 -0
- data/lib/generators/active_agent/{agent_generator.rb → agent/agent_generator.rb} +14 -4
- data/lib/generators/active_agent/install/USAGE +25 -0
- data/lib/generators/active_agent/{install_generator.rb → install/install_generator.rb} +1 -19
- data/lib/generators/active_agent/templates/agent.rb.tt +7 -3
- data/lib/generators/active_agent/templates/application_agent.rb.tt +0 -2
- data/lib/generators/erb/agent_generator.rb +31 -16
- data/lib/generators/erb/templates/instructions.md.erb.tt +3 -0
- data/lib/generators/erb/templates/instructions.md.tt +3 -0
- data/lib/generators/erb/templates/instructions.text.tt +1 -0
- data/lib/generators/erb/templates/message.md.erb.tt +5 -0
- data/lib/generators/erb/templates/schema.json.tt +10 -0
- data/lib/generators/test_unit/agent_generator.rb +1 -1
- data/lib/generators/test_unit/templates/functional_test.rb.tt +4 -2
- metadata +320 -65
- data/lib/active_agent/action_prompt/action.rb +0 -13
- data/lib/active_agent/action_prompt/base.rb +0 -623
- data/lib/active_agent/action_prompt/message.rb +0 -126
- data/lib/active_agent/action_prompt/prompt.rb +0 -136
- data/lib/active_agent/action_prompt.rb +0 -19
- data/lib/active_agent/callbacks.rb +0 -33
- data/lib/active_agent/generation_provider/anthropic_provider.rb +0 -163
- data/lib/active_agent/generation_provider/base.rb +0 -55
- data/lib/active_agent/generation_provider/base_adapter.rb +0 -19
- data/lib/active_agent/generation_provider/error_handling.rb +0 -167
- data/lib/active_agent/generation_provider/log_subscriber.rb +0 -92
- data/lib/active_agent/generation_provider/message_formatting.rb +0 -107
- data/lib/active_agent/generation_provider/ollama_provider.rb +0 -66
- data/lib/active_agent/generation_provider/open_ai_provider.rb +0 -279
- data/lib/active_agent/generation_provider/open_router_provider.rb +0 -385
- data/lib/active_agent/generation_provider/parameter_builder.rb +0 -119
- data/lib/active_agent/generation_provider/response.rb +0 -75
- data/lib/active_agent/generation_provider/responses_adapter.rb +0 -44
- data/lib/active_agent/generation_provider/stream_processing.rb +0 -58
- data/lib/active_agent/generation_provider/tool_management.rb +0 -142
- data/lib/active_agent/generation_provider.rb +0 -67
- data/lib/active_agent/log_subscriber.rb +0 -44
- data/lib/active_agent/parameterized.rb +0 -75
- data/lib/active_agent/prompt_helper.rb +0 -19
- data/lib/active_agent/queued_generation.rb +0 -12
- data/lib/active_agent/rescuable.rb +0 -34
- data/lib/active_agent/sanitizers.rb +0 -40
- data/lib/active_agent/streaming.rb +0 -34
- data/lib/active_agent/test_case.rb +0 -125
- data/lib/generators/USAGE +0 -47
- data/lib/generators/active_agent/USAGE +0 -56
- data/lib/generators/erb/install_generator.rb +0 -44
- data/lib/generators/erb/templates/layout.html.erb.tt +0 -1
- data/lib/generators/erb/templates/layout.json.erb.tt +0 -1
- data/lib/generators/erb/templates/layout.text.erb.tt +0 -1
- data/lib/generators/erb/templates/view.html.erb.tt +0 -5
- data/lib/generators/erb/templates/view.json.erb.tt +0 -16
- /data/lib/active_agent/{preview.rb → concerns/preview.rb} +0 -0
- /data/lib/generators/erb/templates/{view.text.erb.tt → message.text.erb.tt} +0 -0
|
@@ -1,36 +1,458 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
+
require "active_support/core_ext/object/duplicable"
|
|
4
|
+
require "active_support/core_ext/hash/indifferent_access"
|
|
5
|
+
require "erb"
|
|
6
|
+
require "socket"
|
|
7
|
+
require "timeout"
|
|
8
|
+
require "yaml"
|
|
9
|
+
|
|
3
10
|
module ActiveAgent
|
|
11
|
+
# Configuration class for ActiveAgent global settings.
|
|
12
|
+
#
|
|
13
|
+
# Provides configuration options for generation behavior, error handling,
|
|
14
|
+
# and logging. Configuration can be set globally using the
|
|
15
|
+
# {ActiveAgent.configure} method or loaded from a YAML file for
|
|
16
|
+
# provider-specific settings.
|
|
17
|
+
#
|
|
18
|
+
# = Global Configuration
|
|
19
|
+
#
|
|
20
|
+
# Use {ActiveAgent.configure} for framework-level settings like logging.
|
|
21
|
+
#
|
|
22
|
+
# @example Basic configuration
|
|
23
|
+
# ActiveAgent.configure do |config|
|
|
24
|
+
# config.logger = Logger.new(STDOUT)
|
|
25
|
+
# end
|
|
26
|
+
#
|
|
27
|
+
# = Provider Configuration
|
|
28
|
+
#
|
|
29
|
+
# Use YAML configuration files to define provider-specific settings like
|
|
30
|
+
# API keys, models, and parameters. This is the recommended approach for
|
|
31
|
+
# managing multiple generation providers across different environments.
|
|
32
|
+
#
|
|
33
|
+
# @example YAML configuration file (config/activeagent.yml)
|
|
34
|
+
# # Define reusable anchors for common settings
|
|
35
|
+
# openai: &openai
|
|
36
|
+
# service: "OpenAI"
|
|
37
|
+
# access_token: <%= Rails.application.credentials.dig(:openai, :access_token) %>
|
|
38
|
+
#
|
|
39
|
+
# anthropic: &anthropic
|
|
40
|
+
# service: "Anthropic"
|
|
41
|
+
# access_token: <%= Rails.application.credentials.dig(:anthropic, :access_token) %>
|
|
42
|
+
#
|
|
43
|
+
# development:
|
|
44
|
+
# openai:
|
|
45
|
+
# <<: *openai
|
|
46
|
+
# model: "gpt-4o-mini"
|
|
47
|
+
# temperature: 0.7
|
|
48
|
+
# anthropic:
|
|
49
|
+
# <<: *anthropic
|
|
50
|
+
# model: "claude-3-5-sonnet-20241022"
|
|
51
|
+
#
|
|
52
|
+
# production:
|
|
53
|
+
# openai:
|
|
54
|
+
# <<: *openai
|
|
55
|
+
# model: "gpt-4o"
|
|
56
|
+
# temperature: 0.5
|
|
57
|
+
#
|
|
58
|
+
# @example Loading provider configuration
|
|
59
|
+
# # In config/initializers/activeagent.rb
|
|
60
|
+
# ActiveAgent.configuration_load(Rails.root.join("config/activeagent.yml"))
|
|
61
|
+
#
|
|
62
|
+
# @example Using configured providers in agents
|
|
63
|
+
# class MyAgent < ActiveAgent::Base
|
|
64
|
+
# generate_with :openai # Uses settings from config/activeagent.yml
|
|
65
|
+
# end
|
|
66
|
+
#
|
|
67
|
+
# @see ActiveAgent.configure
|
|
68
|
+
# @see ActiveAgent.configuration_load
|
|
4
69
|
class Configuration
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
70
|
+
# Default configuration values.
|
|
71
|
+
#
|
|
72
|
+
# @return [Hash] Hash of default configuration values
|
|
73
|
+
DEFAULTS = {}.freeze
|
|
9
74
|
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
75
|
+
# Gets the logger used by ActiveAgent.
|
|
76
|
+
#
|
|
77
|
+
# @return [Logger] The logger instance
|
|
78
|
+
# @see ActiveAgent::Base.logger
|
|
79
|
+
def logger
|
|
80
|
+
ActiveAgent::Base.logger
|
|
15
81
|
end
|
|
16
82
|
|
|
17
|
-
|
|
18
|
-
|
|
83
|
+
# Sets the logger used by ActiveAgent.
|
|
84
|
+
#
|
|
85
|
+
# @param value [Logger] The logger instance to use
|
|
86
|
+
# @return [Logger] The logger that was set
|
|
87
|
+
#
|
|
88
|
+
# @example
|
|
89
|
+
# config.logger = Logger.new(STDOUT)
|
|
90
|
+
# config.logger.level = Logger::DEBUG
|
|
91
|
+
#
|
|
92
|
+
# @see ActiveAgent::Base.logger=
|
|
93
|
+
def logger=(value)
|
|
94
|
+
ActiveAgent::Base.logger = value
|
|
95
|
+
end
|
|
96
|
+
|
|
97
|
+
# Loads configuration from a YAML file.
|
|
98
|
+
#
|
|
99
|
+
# Reads a YAML configuration file, evaluates any ERB templates, and extracts
|
|
100
|
+
# environment-specific settings based on RAILS_ENV or ENV environment variables.
|
|
101
|
+
# Falls back to the root level settings if no environment key is found.
|
|
102
|
+
#
|
|
103
|
+
# The YAML file contains provider-specific configurations (API keys, models,
|
|
104
|
+
# parameters, retry settings). Provider configurations are stored as nested hashes
|
|
105
|
+
# and can be accessed via the [] operator.
|
|
106
|
+
#
|
|
107
|
+
# @param filename [String] Path to the YAML configuration file
|
|
108
|
+
# @return [Configuration] A new Configuration instance with loaded settings
|
|
109
|
+
#
|
|
110
|
+
# @example Provider-specific configuration with YAML anchors
|
|
111
|
+
# # config/activeagent.yml
|
|
112
|
+
# openai: &openai
|
|
113
|
+
# service: "OpenAI"
|
|
114
|
+
# access_token: <%= Rails.application.credentials.dig(:openai, :access_token) %>
|
|
115
|
+
# max_retries: 3
|
|
116
|
+
#
|
|
117
|
+
# anthropic: &anthropic
|
|
118
|
+
# service: "Anthropic"
|
|
119
|
+
# access_token: <%= Rails.application.credentials.dig(:anthropic, :access_token) %>
|
|
120
|
+
# max_retries: 5
|
|
121
|
+
#
|
|
122
|
+
# open_router: &open_router
|
|
123
|
+
# service: "OpenRouter"
|
|
124
|
+
# access_token: <%= Rails.application.credentials.dig(:open_router, :access_token) %>
|
|
125
|
+
#
|
|
126
|
+
# development:
|
|
127
|
+
# openai:
|
|
128
|
+
# <<: *openai
|
|
129
|
+
# model: "gpt-4o-mini"
|
|
130
|
+
# temperature: 0.7
|
|
131
|
+
# anthropic:
|
|
132
|
+
# <<: *anthropic
|
|
133
|
+
# model: "claude-3-5-sonnet-20241022"
|
|
134
|
+
# open_router:
|
|
135
|
+
# <<: *open_router
|
|
136
|
+
# model: "qwen/qwen3-30b-a3b:free"
|
|
137
|
+
#
|
|
138
|
+
# test:
|
|
139
|
+
# openai:
|
|
140
|
+
# <<: *openai
|
|
141
|
+
# model: "gpt-4o-mini"
|
|
142
|
+
# anthropic:
|
|
143
|
+
# <<: *anthropic
|
|
144
|
+
#
|
|
145
|
+
# production:
|
|
146
|
+
# openai:
|
|
147
|
+
# <<: *openai
|
|
148
|
+
# model: "gpt-4o"
|
|
149
|
+
# temperature: 0.5
|
|
150
|
+
# anthropic:
|
|
151
|
+
# <<: *anthropic
|
|
152
|
+
# model: "claude-3-5-sonnet-20241022"
|
|
153
|
+
#
|
|
154
|
+
# @example Loading and accessing provider configuration
|
|
155
|
+
# config = ActiveAgent::Configuration.load("config/activeagent.yml")
|
|
156
|
+
# config[:openai] # => { "service" => "OpenAI", "model" => "gpt-4o-mini", ... }
|
|
157
|
+
#
|
|
158
|
+
# @note ERB templates are evaluated, allowing you to use Rails credentials,
|
|
159
|
+
# environment variables, or any Ruby code within <%= %> tags.
|
|
160
|
+
def self.load(filename)
|
|
161
|
+
settings = {}
|
|
162
|
+
|
|
163
|
+
if File.exist?(filename)
|
|
164
|
+
config_file = YAML.load(ERB.new(File.read(filename)).result, aliases: true)
|
|
165
|
+
env = ENV["RAILS_ENV"] || ENV["ENV"] || "development"
|
|
166
|
+
settings = config_file[env] || config_file
|
|
167
|
+
end
|
|
168
|
+
|
|
169
|
+
Configuration.new(settings)
|
|
170
|
+
end
|
|
171
|
+
|
|
172
|
+
# Initializes a new Configuration instance with default values.
|
|
173
|
+
#
|
|
174
|
+
# Sets all configuration attributes to their default values as defined
|
|
175
|
+
# in {DEFAULTS}. Duplicates values where possible to prevent shared state.
|
|
176
|
+
# Custom settings can be passed to override defaults.
|
|
177
|
+
#
|
|
178
|
+
# When loading from a YAML file via {Configuration.load}, all settings from
|
|
179
|
+
# the environment-specific section are passed as the settings hash, including
|
|
180
|
+
# Initializes a new Configuration instance with optional settings.
|
|
181
|
+
#
|
|
182
|
+
# Settings typically come from a YAML configuration file loaded via {.load}.
|
|
183
|
+
# The configuration object stores provider-specific settings as nested hashes.
|
|
184
|
+
#
|
|
185
|
+
# @param settings [Hash] Optional settings to load
|
|
186
|
+
#
|
|
187
|
+
# @example With default settings
|
|
188
|
+
# config = ActiveAgent::Configuration.new
|
|
189
|
+
#
|
|
190
|
+
# @example With provider configurations (typically from YAML)
|
|
191
|
+
# config = ActiveAgent::Configuration.new(
|
|
192
|
+
# openai: { service: "OpenAI", model: "gpt-4o" },
|
|
193
|
+
# anthropic: { service: "Anthropic", model: "claude-3-5-sonnet-20241022" }
|
|
194
|
+
# )
|
|
195
|
+
def initialize(settings = {})
|
|
196
|
+
(DEFAULTS.merge(settings)).each do |key, value|
|
|
197
|
+
self[key] = value
|
|
198
|
+
end
|
|
19
199
|
end
|
|
20
|
-
end
|
|
21
200
|
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
201
|
+
# Retrieves a configuration value by key.
|
|
202
|
+
#
|
|
203
|
+
# This method provides hash-like access to provider configurations.
|
|
204
|
+
# Provider configurations are stored as nested hashes.
|
|
205
|
+
#
|
|
206
|
+
# @param key [String, Symbol] Configuration key to retrieve
|
|
207
|
+
# @return [Object, nil] The configuration value or nil if not found
|
|
208
|
+
#
|
|
209
|
+
# @example Accessing provider configurations
|
|
210
|
+
# config[:openai] # => { "service" => "OpenAI", "model" => "gpt-4o", ... }
|
|
211
|
+
# config[:anthropic] # => { "service" => "Anthropic", "model" => "claude-3-5-sonnet-20241022", ... }
|
|
212
|
+
def [](key)
|
|
213
|
+
instance_variable_get("@#{key}")
|
|
25
214
|
end
|
|
26
215
|
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
216
|
+
# Sets a configuration value by key.
|
|
217
|
+
#
|
|
218
|
+
# @param key [String, Symbol] Configuration key to set
|
|
219
|
+
# @param value [Object] Value to set
|
|
220
|
+
# @return [Object] The value that was set
|
|
221
|
+
#
|
|
222
|
+
# @example
|
|
223
|
+
# config[:retries] = false
|
|
224
|
+
# config["retries_count"] = 5
|
|
225
|
+
def []=(key, value)
|
|
226
|
+
instance_variable_set("@#{key}", convert_to_indifferent_access(value))
|
|
227
|
+
end
|
|
228
|
+
|
|
229
|
+
# Extracts nested values using a sequence of keys.
|
|
230
|
+
#
|
|
231
|
+
# Similar to Hash#dig, traverses nested configuration values safely.
|
|
232
|
+
# Returns nil if any intermediate key doesn't exist.
|
|
233
|
+
#
|
|
234
|
+
# @param keys [Array<String, Symbol>] Keys to traverse
|
|
235
|
+
# @return [Object, nil] The nested value or nil
|
|
236
|
+
#
|
|
237
|
+
# @example
|
|
238
|
+
# config.dig(:openai, :model) # => "gpt-4o"
|
|
239
|
+
# config.dig("test", "anthropic", "service") # => "Anthropic"
|
|
240
|
+
# config.dig(:nonexistent, :key) # => nil
|
|
241
|
+
def dig(*keys)
|
|
242
|
+
keys.reduce(self) do |obj, key|
|
|
243
|
+
break nil unless obj
|
|
244
|
+
if obj.is_a?(Configuration)
|
|
245
|
+
obj[key]
|
|
246
|
+
elsif obj.respond_to?(:dig)
|
|
247
|
+
obj.dig(key)
|
|
248
|
+
elsif obj.respond_to?(:[])
|
|
249
|
+
obj[key]
|
|
250
|
+
else
|
|
251
|
+
nil
|
|
252
|
+
end
|
|
253
|
+
end
|
|
254
|
+
end
|
|
255
|
+
|
|
256
|
+
# Creates a deep duplicate of the configuration.
|
|
257
|
+
#
|
|
258
|
+
# Recursively duplicates all configuration values to avoid shared state.
|
|
259
|
+
#
|
|
260
|
+
# @return [Configuration] A new Configuration instance with duplicated values
|
|
261
|
+
#
|
|
262
|
+
# @example
|
|
263
|
+
# original = ActiveAgent.configuration
|
|
264
|
+
# backup = original.deep_dup
|
|
265
|
+
# backup[:openai] = { service: "OpenAI" } # doesn't affect original
|
|
266
|
+
def deep_dup
|
|
267
|
+
new_config = Configuration.new
|
|
268
|
+
instance_variables.each do |var|
|
|
269
|
+
value = instance_variable_get(var)
|
|
270
|
+
new_config.instance_variable_set(var, deep_dup_value(value))
|
|
271
|
+
end
|
|
272
|
+
new_config
|
|
273
|
+
end
|
|
274
|
+
|
|
275
|
+
# Replaces the current configuration values with those from another configuration.
|
|
276
|
+
#
|
|
277
|
+
# Copies all instance variables from the source configuration to this one,
|
|
278
|
+
# and removes any instance variables that exist in self but not in other.
|
|
279
|
+
# Useful for restoring configuration state in tests.
|
|
280
|
+
#
|
|
281
|
+
# @param other [Configuration] The configuration to copy from
|
|
282
|
+
# @return [Configuration] Self
|
|
283
|
+
#
|
|
284
|
+
# @example
|
|
285
|
+
# backup = config.deep_dup
|
|
286
|
+
# # ... make changes ...
|
|
287
|
+
# config.replace(backup) # restore original state
|
|
288
|
+
def replace(other)
|
|
289
|
+
# Remove variables that exist in self but not in other
|
|
290
|
+
(instance_variables - other.instance_variables).each do |var|
|
|
291
|
+
remove_instance_variable(var)
|
|
292
|
+
end
|
|
293
|
+
|
|
294
|
+
# Copy all variables from other to self
|
|
295
|
+
other.instance_variables.each do |var|
|
|
296
|
+
instance_variable_set(var, other.instance_variable_get(var))
|
|
297
|
+
end
|
|
298
|
+
|
|
299
|
+
self
|
|
30
300
|
end
|
|
31
301
|
|
|
32
|
-
|
|
33
|
-
|
|
302
|
+
# Delegates method calls to the [] operator for accessing configuration values.
|
|
303
|
+
#
|
|
304
|
+
# Allows accessing configuration values using method syntax instead of
|
|
305
|
+
# hash-like access. Returns nil for undefined configuration keys.
|
|
306
|
+
#
|
|
307
|
+
# @param method [Symbol] The method name (configuration key)
|
|
308
|
+
# @param args [Array] Method arguments (not used)
|
|
309
|
+
# @return [Object, nil] The configuration value or nil
|
|
310
|
+
# @private
|
|
311
|
+
#
|
|
312
|
+
# @example
|
|
313
|
+
# config.retries # => true (same as config[:retries])
|
|
314
|
+
# config.retries_count # => 3 (same as config[:retries_count])
|
|
315
|
+
def method_missing(method, *args)
|
|
316
|
+
self[method]
|
|
34
317
|
end
|
|
318
|
+
|
|
319
|
+
# Checks if the configuration responds to a method.
|
|
320
|
+
#
|
|
321
|
+
# Returns true if an instance variable exists for the given method name,
|
|
322
|
+
# allowing proper introspection of dynamically accessible configuration keys.
|
|
323
|
+
#
|
|
324
|
+
# @param method [Symbol] The method name to check
|
|
325
|
+
# @param include_private [Boolean] Whether to include private methods
|
|
326
|
+
# @return [Boolean] True if the configuration has the key
|
|
327
|
+
# @private
|
|
328
|
+
def respond_to_missing?(method, include_private = false)
|
|
329
|
+
instance_variable_defined?("@#{method}") || super
|
|
330
|
+
end
|
|
331
|
+
|
|
332
|
+
private
|
|
333
|
+
|
|
334
|
+
# Recursively converts hashes to HashWithIndifferentAccess.
|
|
335
|
+
#
|
|
336
|
+
# This ensures that all hash values (including nested hashes) can be
|
|
337
|
+
# accessed using both string and symbol keys. Non-hash values are
|
|
338
|
+
# returned unchanged.
|
|
339
|
+
#
|
|
340
|
+
# @param value [Object] The value to convert
|
|
341
|
+
# @return [Object] The converted value
|
|
342
|
+
# @private
|
|
343
|
+
def convert_to_indifferent_access(value)
|
|
344
|
+
case value
|
|
345
|
+
when Hash
|
|
346
|
+
value.with_indifferent_access.transform_values { |v| convert_to_indifferent_access(v) }
|
|
347
|
+
when Array
|
|
348
|
+
value.map { |v| convert_to_indifferent_access(v) }
|
|
349
|
+
else
|
|
350
|
+
value
|
|
351
|
+
end
|
|
352
|
+
end
|
|
353
|
+
|
|
354
|
+
# Recursively duplicates a value.
|
|
355
|
+
#
|
|
356
|
+
# Creates deep copies of hashes and arrays to avoid shared state.
|
|
357
|
+
# Uses dup for duplicable objects, returns non-duplicable objects as-is.
|
|
358
|
+
#
|
|
359
|
+
# @param value [Object] The value to duplicate
|
|
360
|
+
# @return [Object] The duplicated value
|
|
361
|
+
# @private
|
|
362
|
+
def deep_dup_value(value)
|
|
363
|
+
case value
|
|
364
|
+
when Hash
|
|
365
|
+
value.transform_values { |v| deep_dup_value(v) }
|
|
366
|
+
when Array
|
|
367
|
+
value.map { |v| deep_dup_value(v) }
|
|
368
|
+
else
|
|
369
|
+
value.duplicable? ? value.dup : value
|
|
370
|
+
end
|
|
371
|
+
end
|
|
372
|
+
end
|
|
373
|
+
|
|
374
|
+
# Returns the global configuration instance.
|
|
375
|
+
#
|
|
376
|
+
# Creates a new {Configuration} instance if one doesn't exist.
|
|
377
|
+
#
|
|
378
|
+
# @return [Configuration] The global configuration instance
|
|
379
|
+
#
|
|
380
|
+
# @example Access configuration
|
|
381
|
+
# ActiveAgent.configuration.retries # => true
|
|
382
|
+
def self.configuration
|
|
383
|
+
@configuration ||= Configuration.new
|
|
384
|
+
end
|
|
385
|
+
|
|
386
|
+
# Configures ActiveAgent with a block.
|
|
387
|
+
#
|
|
388
|
+
# Yields the global configuration instance to the provided block,
|
|
389
|
+
# allowing settings to be modified. This is the recommended way
|
|
390
|
+
# to configure ActiveAgent.
|
|
391
|
+
#
|
|
392
|
+
# @yield [config] Yields the configuration instance
|
|
393
|
+
# @yieldparam config [Configuration] The configuration to modify
|
|
394
|
+
# @return [Configuration] The modified configuration instance
|
|
395
|
+
#
|
|
396
|
+
# @example Custom logger (non-Rails environments)
|
|
397
|
+
# ActiveAgent.configure do |config|
|
|
398
|
+
# config.logger = Logger.new(STDOUT)
|
|
399
|
+
# config.logger.level = Logger::DEBUG
|
|
400
|
+
# end
|
|
401
|
+
def self.configure
|
|
402
|
+
yield configuration if block_given?
|
|
403
|
+
configuration
|
|
404
|
+
end
|
|
405
|
+
|
|
406
|
+
# Resets the global configuration to default values.
|
|
407
|
+
#
|
|
408
|
+
# Creates a new {Configuration} instance with all defaults restored.
|
|
409
|
+
# Useful for testing or resetting state.
|
|
410
|
+
#
|
|
411
|
+
# @return [Configuration] The new default configuration instance
|
|
412
|
+
#
|
|
413
|
+
# @example
|
|
414
|
+
# ActiveAgent.reset_configuration!
|
|
415
|
+
def self.reset_configuration!
|
|
416
|
+
@configuration = Configuration.new
|
|
417
|
+
end
|
|
418
|
+
|
|
419
|
+
# Loads and sets the global configuration from a YAML file.
|
|
420
|
+
#
|
|
421
|
+
# Reads configuration from the specified file and sets it as the
|
|
422
|
+
# global configuration instance. This is an alternative to using
|
|
423
|
+
# {.configure} with a block and is the recommended approach for
|
|
424
|
+
# managing provider-specific settings.
|
|
425
|
+
#
|
|
426
|
+
# The YAML file supports ERB templating, environment-specific sections,
|
|
427
|
+
# and YAML anchors for reusing common configuration blocks across providers.
|
|
428
|
+
#
|
|
429
|
+
# @param filename [String] Path to the YAML configuration file
|
|
430
|
+
# @return [Configuration] The loaded configuration instance
|
|
431
|
+
#
|
|
432
|
+
# @example Basic usage in Rails initializer
|
|
433
|
+
# # config/initializers/activeagent.rb
|
|
434
|
+
# ActiveAgent.configuration_load(Rails.root.join("config/activeagent.yml"))
|
|
435
|
+
#
|
|
436
|
+
# @example Complete workflow
|
|
437
|
+
# # 1. Create config/activeagent.yml with provider settings
|
|
438
|
+
# # 2. Load in initializer:
|
|
439
|
+
# ActiveAgent.configuration_load("config/activeagent.yml")
|
|
440
|
+
#
|
|
441
|
+
# # 3. Use in your agents:
|
|
442
|
+
# class MyAgent < ActiveAgent::Base
|
|
443
|
+
# generate_with :openai # Automatically uses config from YAML
|
|
444
|
+
# end
|
|
445
|
+
#
|
|
446
|
+
# @example Accessing loaded provider configuration
|
|
447
|
+
# ActiveAgent.configuration[:openai]
|
|
448
|
+
# # => { "service" => "OpenAI", "model" => "gpt-4o-mini", "temperature" => 0.7, ... }
|
|
449
|
+
#
|
|
450
|
+
# @note This method is typically called once during application initialization.
|
|
451
|
+
# Store API keys in Rails credentials rather than directly in the YAML file.
|
|
452
|
+
#
|
|
453
|
+
# @see Configuration.load
|
|
454
|
+
# @see .configure
|
|
455
|
+
def self.configuration_load(filename)
|
|
456
|
+
@configuration = Configuration.load(filename)
|
|
35
457
|
end
|
|
36
458
|
end
|