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
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
require_relative "_base_provider"
|
|
2
|
+
|
|
3
|
+
require_gem!(:openai, __FILE__)
|
|
4
|
+
|
|
5
|
+
require_relative "open_ai_provider"
|
|
6
|
+
require_relative "ollama/_types"
|
|
7
|
+
|
|
8
|
+
module ActiveAgent
|
|
9
|
+
module Providers
|
|
10
|
+
# Connects to local Ollama instances via OpenAI-compatible API.
|
|
11
|
+
#
|
|
12
|
+
# Provides chat completion and embedding functionality through locally-hosted
|
|
13
|
+
# Ollama models. Handles connection errors specific to local deployments.
|
|
14
|
+
#
|
|
15
|
+
# @see OpenAI::ChatProvider
|
|
16
|
+
class OllamaProvider < OpenAI::ChatProvider
|
|
17
|
+
# @return [String]
|
|
18
|
+
def self.service_name
|
|
19
|
+
"Ollama"
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
# @return [Class]
|
|
23
|
+
def self.options_klass
|
|
24
|
+
namespace::Options
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
# @return [ActiveModel::Type::Value]
|
|
28
|
+
def self.prompt_request_type
|
|
29
|
+
namespace::Chat::RequestType.new
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
# @return [ActiveModel::Type::Value]
|
|
33
|
+
def self.embed_request_type
|
|
34
|
+
namespace::Embedding::RequestType.new
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
protected
|
|
38
|
+
|
|
39
|
+
# Executes chat completion request with Ollama-specific error handling.
|
|
40
|
+
#
|
|
41
|
+
# @see OpenAI::ChatProvider#api_prompt_execute
|
|
42
|
+
# @param parameters [Hash]
|
|
43
|
+
# @return [Object, nil] response object or nil for streaming
|
|
44
|
+
# @raise [OpenAI::Errors::APIConnectionError] when Ollama server unreachable
|
|
45
|
+
def api_prompt_execute(parameters)
|
|
46
|
+
super
|
|
47
|
+
|
|
48
|
+
rescue ::OpenAI::Errors::APIConnectionError => exception
|
|
49
|
+
log_connection_error(exception)
|
|
50
|
+
raise exception
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
# Executes embedding request with Ollama-specific error handling.
|
|
54
|
+
#
|
|
55
|
+
# @param parameters [Hash]
|
|
56
|
+
# @return [Hash] symbolized API response
|
|
57
|
+
# @raise [OpenAI::Errors::APIConnectionError] when Ollama server unreachable
|
|
58
|
+
def api_embed_execute(parameters)
|
|
59
|
+
instrument("embeddings_request.provider.active_agent")
|
|
60
|
+
client.embeddings.create(**parameters).as_json.deep_symbolize_keys
|
|
61
|
+
|
|
62
|
+
rescue ::OpenAI::Errors::APIConnectionError => exception
|
|
63
|
+
log_connection_error(exception)
|
|
64
|
+
raise exception
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
# Handles role duplication bug in Ollama's OpenAI-compatible streaming.
|
|
68
|
+
#
|
|
69
|
+
# Ollama duplicates role information in streaming deltas, requiring
|
|
70
|
+
# manual cleanup to prevent message corruption. This fixes the
|
|
71
|
+
# "role appears in every chunk" issue when using streaming responses.
|
|
72
|
+
#
|
|
73
|
+
# @see OpenAI::ChatProvider#message_merge_delta
|
|
74
|
+
# @param message [Hash]
|
|
75
|
+
# @param delta [Hash]
|
|
76
|
+
# @return [Hash]
|
|
77
|
+
def message_merge_delta(message, delta)
|
|
78
|
+
message[:role] = delta.delete(:role) if delta[:role] # Copy a Bad Design (OpenAI's Chat API) Badly, Win Bad Prizes
|
|
79
|
+
|
|
80
|
+
hash_merge_delta(message, delta)
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
# Logs connection failures with Ollama server details for debugging.
|
|
84
|
+
#
|
|
85
|
+
# @param error [Exception]
|
|
86
|
+
# @return [void]
|
|
87
|
+
def log_connection_error(error)
|
|
88
|
+
instrument("connection_error.provider.active_agent",
|
|
89
|
+
uri_base: options.uri_base,
|
|
90
|
+
exception: error.class,
|
|
91
|
+
message: error.message)
|
|
92
|
+
end
|
|
93
|
+
end
|
|
94
|
+
end
|
|
95
|
+
end
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
require_relative "../_base_provider"
|
|
2
|
+
|
|
3
|
+
require_gem!(:openai, __FILE__)
|
|
4
|
+
|
|
5
|
+
require_relative "options"
|
|
6
|
+
|
|
7
|
+
module ActiveAgent
|
|
8
|
+
module Providers
|
|
9
|
+
module OpenAI
|
|
10
|
+
# Base provider class for OpenAI API implementations.
|
|
11
|
+
#
|
|
12
|
+
# Provides common functionality for OpenAI-based providers including
|
|
13
|
+
# client configuration, service identification, and tool call processing.
|
|
14
|
+
#
|
|
15
|
+
# @see ActiveAgent::Providers::BaseProvider
|
|
16
|
+
class Base < ActiveAgent::Providers::BaseProvider
|
|
17
|
+
# Returns the service name for OpenAI providers.
|
|
18
|
+
#
|
|
19
|
+
# @return [String] Always returns "OpenAI"
|
|
20
|
+
def self.service_name
|
|
21
|
+
"OpenAI"
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
# Returns a configured OpenAI client instance.
|
|
25
|
+
#
|
|
26
|
+
# @return [OpenAI::Client] The configured OpenAI client
|
|
27
|
+
def client
|
|
28
|
+
::OpenAI::Client.new(**options.serialize)
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
protected
|
|
32
|
+
|
|
33
|
+
# Processes a tool call function from the API response.
|
|
34
|
+
#
|
|
35
|
+
# This method extracts the function name and arguments from an API function call,
|
|
36
|
+
# parses the arguments as JSON, and invokes the function callback with the parsed parameters.
|
|
37
|
+
#
|
|
38
|
+
# @param api_function_call [Hash] The function call data from the API response
|
|
39
|
+
# @option api_function_call [String] :name The name of the function to call
|
|
40
|
+
# @option api_function_call [String] :arguments JSON string containing the function arguments
|
|
41
|
+
#
|
|
42
|
+
# @return [Object] The result of the function callback invocation
|
|
43
|
+
#
|
|
44
|
+
# @example Processing a tool call
|
|
45
|
+
# api_call = { name: "get_weather", arguments: '{"location":"NYC"}' }
|
|
46
|
+
# process_tool_call_function(api_call)
|
|
47
|
+
# # => calls tools_function.call("get_weather", location: "NYC")
|
|
48
|
+
def process_tool_call_function(api_function_call)
|
|
49
|
+
name = api_function_call[:name]
|
|
50
|
+
kwargs = JSON.parse(api_function_call[:arguments], symbolize_names: true) if api_function_call[:arguments]
|
|
51
|
+
|
|
52
|
+
instrument("tool_execution.provider.active_agent", tool_name: name)
|
|
53
|
+
tools_function.call(name, **kwargs)
|
|
54
|
+
end
|
|
55
|
+
end
|
|
56
|
+
end
|
|
57
|
+
end
|
|
58
|
+
end
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require_relative "request"
|
|
4
|
+
|
|
5
|
+
module ActiveAgent
|
|
6
|
+
module Providers
|
|
7
|
+
module OpenAI
|
|
8
|
+
module Chat
|
|
9
|
+
# Type for Request model
|
|
10
|
+
class RequestType < ActiveModel::Type::Value
|
|
11
|
+
def cast(value)
|
|
12
|
+
case value
|
|
13
|
+
when Request
|
|
14
|
+
value
|
|
15
|
+
when Hash
|
|
16
|
+
Request.new(**value.deep_symbolize_keys)
|
|
17
|
+
when nil
|
|
18
|
+
nil
|
|
19
|
+
else
|
|
20
|
+
raise ArgumentError, "Cannot cast #{value.class} to Request"
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def serialize(value)
|
|
25
|
+
case value
|
|
26
|
+
when Request
|
|
27
|
+
value.serialize
|
|
28
|
+
when Hash
|
|
29
|
+
value
|
|
30
|
+
when nil
|
|
31
|
+
nil
|
|
32
|
+
else
|
|
33
|
+
raise ArgumentError, "Cannot serialize #{value.class}"
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
def deserialize(value)
|
|
38
|
+
cast(value)
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
end
|
|
@@ -0,0 +1,215 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "active_agent/providers/common/model"
|
|
4
|
+
require_relative "requests/_types"
|
|
5
|
+
|
|
6
|
+
module ActiveAgent
|
|
7
|
+
module Providers
|
|
8
|
+
module OpenAI
|
|
9
|
+
module Chat
|
|
10
|
+
class Request < Common::BaseModel
|
|
11
|
+
# Messages array (required)
|
|
12
|
+
attribute :messages, Requests::Messages::MessagesType.new
|
|
13
|
+
|
|
14
|
+
# Model ID (required)
|
|
15
|
+
attribute :model, :string
|
|
16
|
+
|
|
17
|
+
# Audio output parameters
|
|
18
|
+
attribute :audio, Requests::AudioType.new
|
|
19
|
+
|
|
20
|
+
# Frequency penalty
|
|
21
|
+
attribute :frequency_penalty, :float, default: 0
|
|
22
|
+
|
|
23
|
+
# Deprecated: function_call (use tool_choice instead)
|
|
24
|
+
attribute :function_call # String or object
|
|
25
|
+
|
|
26
|
+
# Deprecated: functions (use tools instead)
|
|
27
|
+
attribute :functions # Array of function objects
|
|
28
|
+
|
|
29
|
+
# Logit bias
|
|
30
|
+
attribute :logit_bias # Hash of token_id => bias_value
|
|
31
|
+
|
|
32
|
+
# Log probabilities
|
|
33
|
+
attribute :logprobs, :boolean, default: false
|
|
34
|
+
|
|
35
|
+
# Max completion tokens
|
|
36
|
+
attribute :max_completion_tokens, :integer
|
|
37
|
+
|
|
38
|
+
# Deprecated: max_tokens (use max_completion_tokens)
|
|
39
|
+
attribute :max_tokens, :integer
|
|
40
|
+
|
|
41
|
+
# Metadata
|
|
42
|
+
attribute :metadata # Hash of key-value pairs
|
|
43
|
+
|
|
44
|
+
# Modalities
|
|
45
|
+
attribute :modalities, default: -> { [ "text" ] } # Array of strings
|
|
46
|
+
|
|
47
|
+
# Number of completions
|
|
48
|
+
attribute :n, :integer, default: 1
|
|
49
|
+
|
|
50
|
+
# Parallel tool calls
|
|
51
|
+
attribute :parallel_tool_calls, :boolean, default: true
|
|
52
|
+
|
|
53
|
+
# Prediction configuration
|
|
54
|
+
attribute :prediction, Requests::PredictionType.new
|
|
55
|
+
|
|
56
|
+
# Presence penalty
|
|
57
|
+
attribute :presence_penalty, :float, default: 0
|
|
58
|
+
|
|
59
|
+
# Prompt cache key
|
|
60
|
+
attribute :prompt_cache_key, :string
|
|
61
|
+
|
|
62
|
+
# Reasoning effort (for reasoning models)
|
|
63
|
+
attribute :reasoning_effort, :string
|
|
64
|
+
|
|
65
|
+
# Response format
|
|
66
|
+
attribute :response_format, Requests::ResponseFormatType.new
|
|
67
|
+
|
|
68
|
+
# Safety identifier
|
|
69
|
+
attribute :safety_identifier, :string
|
|
70
|
+
|
|
71
|
+
# Deprecated: seed
|
|
72
|
+
attribute :seed, :integer
|
|
73
|
+
|
|
74
|
+
# Service tier
|
|
75
|
+
attribute :service_tier, :string, default: "auto"
|
|
76
|
+
|
|
77
|
+
# Stop sequences
|
|
78
|
+
attribute :stop # String, array, or null
|
|
79
|
+
|
|
80
|
+
# Storage
|
|
81
|
+
attribute :store, :boolean, default: false
|
|
82
|
+
|
|
83
|
+
# Streaming
|
|
84
|
+
attribute :stream, :boolean, default: false
|
|
85
|
+
attribute :stream_options, Requests::StreamOptionsType.new
|
|
86
|
+
|
|
87
|
+
# Temperature sampling
|
|
88
|
+
attribute :temperature, :float, default: 1
|
|
89
|
+
|
|
90
|
+
# Tool choice
|
|
91
|
+
attribute :tool_choice, Requests::ToolChoiceType.new
|
|
92
|
+
|
|
93
|
+
# Tools array
|
|
94
|
+
attribute :tools # Array of tool objects
|
|
95
|
+
|
|
96
|
+
# Top logprobs
|
|
97
|
+
attribute :top_logprobs, :integer
|
|
98
|
+
|
|
99
|
+
# Top P sampling
|
|
100
|
+
attribute :top_p, :float, default: 1
|
|
101
|
+
|
|
102
|
+
# Deprecated: user (use safety_identifier or prompt_cache_key)
|
|
103
|
+
attribute :user, :string
|
|
104
|
+
|
|
105
|
+
# Verbosity (for reasoning models)
|
|
106
|
+
attribute :verbosity, :string
|
|
107
|
+
|
|
108
|
+
# Web search options
|
|
109
|
+
attribute :web_search_options, Requests::WebSearchOptionsType.new
|
|
110
|
+
|
|
111
|
+
# Validations
|
|
112
|
+
validates :model, :messages, presence: true
|
|
113
|
+
|
|
114
|
+
validates :frequency_penalty, numericality: { greater_than_or_equal_to: -2.0, less_than_or_equal_to: 2.0 }, allow_nil: true
|
|
115
|
+
validates :presence_penalty, numericality: { greater_than_or_equal_to: -2.0, less_than_or_equal_to: 2.0 }, allow_nil: true
|
|
116
|
+
validates :temperature, numericality: { greater_than_or_equal_to: 0, less_than_or_equal_to: 2 }, allow_nil: true
|
|
117
|
+
validates :top_p, numericality: { greater_than_or_equal_to: 0, less_than_or_equal_to: 1 }, allow_nil: true
|
|
118
|
+
validates :top_logprobs, numericality: { greater_than_or_equal_to: 0, less_than_or_equal_to: 20 }, allow_nil: true
|
|
119
|
+
validates :n, numericality: { greater_than: 0 }, allow_nil: true
|
|
120
|
+
validates :max_completion_tokens, numericality: { greater_than: 0 }, allow_nil: true
|
|
121
|
+
validates :max_tokens, numericality: { greater_than: 0 }, allow_nil: true
|
|
122
|
+
|
|
123
|
+
validates :service_tier, inclusion: { in: %w[auto default flex priority] }, allow_nil: true
|
|
124
|
+
validates :reasoning_effort, inclusion: { in: %w[minimal low medium high] }, allow_nil: true
|
|
125
|
+
validates :verbosity, inclusion: { in: %w[low medium high] }, allow_nil: true
|
|
126
|
+
validates :modalities, inclusion: { in: %w[text audio] }, allow_nil: true
|
|
127
|
+
|
|
128
|
+
# Custom validations
|
|
129
|
+
validate :validate_metadata_format
|
|
130
|
+
validate :validate_logit_bias_format
|
|
131
|
+
validate :validate_stop_sequences
|
|
132
|
+
|
|
133
|
+
def serialize
|
|
134
|
+
super.tap do |hash|
|
|
135
|
+
# Can be an empty hash, to enable the feature
|
|
136
|
+
hash[:web_search_options] ||= {} if web_search_options
|
|
137
|
+
end
|
|
138
|
+
end
|
|
139
|
+
|
|
140
|
+
# Common Format Compatability
|
|
141
|
+
def instructions=(*values)
|
|
142
|
+
self.messages ||= []
|
|
143
|
+
|
|
144
|
+
values.flatten.reverse.each do |value|
|
|
145
|
+
self.messages.unshift({ role: "developer", content: value })
|
|
146
|
+
end
|
|
147
|
+
end
|
|
148
|
+
|
|
149
|
+
# Common Format Compatability
|
|
150
|
+
alias_attribute :message, :messages
|
|
151
|
+
|
|
152
|
+
# Common Format Compatability
|
|
153
|
+
def messages=(value)
|
|
154
|
+
case value
|
|
155
|
+
when Array
|
|
156
|
+
super((messages || []) | value)
|
|
157
|
+
else
|
|
158
|
+
super((messages || []) | [ value ])
|
|
159
|
+
end
|
|
160
|
+
end
|
|
161
|
+
|
|
162
|
+
private
|
|
163
|
+
|
|
164
|
+
def validate_metadata_format
|
|
165
|
+
return if metadata.nil?
|
|
166
|
+
|
|
167
|
+
unless metadata.is_a?(Hash)
|
|
168
|
+
errors.add(:metadata, "must be a hash")
|
|
169
|
+
return
|
|
170
|
+
end
|
|
171
|
+
|
|
172
|
+
metadata.each do |key, value|
|
|
173
|
+
if key.to_s.length > 64
|
|
174
|
+
errors.add(:metadata, "keys must be 64 characters or less")
|
|
175
|
+
end
|
|
176
|
+
if value.to_s.length > 512
|
|
177
|
+
errors.add(:metadata, "values must be 512 characters or less")
|
|
178
|
+
end
|
|
179
|
+
end
|
|
180
|
+
|
|
181
|
+
if metadata.size > 16
|
|
182
|
+
errors.add(:metadata, "must have 16 key-value pairs or less")
|
|
183
|
+
end
|
|
184
|
+
end
|
|
185
|
+
|
|
186
|
+
def validate_logit_bias_format
|
|
187
|
+
return if logit_bias.nil?
|
|
188
|
+
|
|
189
|
+
unless logit_bias.is_a?(Hash)
|
|
190
|
+
errors.add(:logit_bias, "must be a hash")
|
|
191
|
+
return
|
|
192
|
+
end
|
|
193
|
+
|
|
194
|
+
logit_bias.each do |token_id, bias|
|
|
195
|
+
unless bias.is_a?(Numeric) && bias >= -100 && bias <= 100
|
|
196
|
+
errors.add(:logit_bias, "bias values must be between -100 and 100")
|
|
197
|
+
end
|
|
198
|
+
end
|
|
199
|
+
end
|
|
200
|
+
|
|
201
|
+
def validate_stop_sequences
|
|
202
|
+
return if stop.nil?
|
|
203
|
+
return if stop.is_a?(String)
|
|
204
|
+
|
|
205
|
+
if stop.is_a?(Array)
|
|
206
|
+
errors.add(:stop, "can have at most 4 sequences") if stop.length > 4
|
|
207
|
+
else
|
|
208
|
+
errors.add(:stop, "must be a string, array, or null")
|
|
209
|
+
end
|
|
210
|
+
end
|
|
211
|
+
end
|
|
212
|
+
end
|
|
213
|
+
end
|
|
214
|
+
end
|
|
215
|
+
end
|
|
@@ -0,0 +1,229 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require_relative "messages/_types"
|
|
4
|
+
require_relative "tools/_types"
|
|
5
|
+
|
|
6
|
+
require_relative "audio"
|
|
7
|
+
require_relative "prediction"
|
|
8
|
+
require_relative "response_format"
|
|
9
|
+
require_relative "stream_options"
|
|
10
|
+
require_relative "tool_choice"
|
|
11
|
+
require_relative "web_search_options"
|
|
12
|
+
|
|
13
|
+
module ActiveAgent
|
|
14
|
+
module Providers
|
|
15
|
+
module OpenAI
|
|
16
|
+
module Chat
|
|
17
|
+
module Requests
|
|
18
|
+
# Type for Audio
|
|
19
|
+
class AudioType < ActiveModel::Type::Value
|
|
20
|
+
def cast(value)
|
|
21
|
+
case value
|
|
22
|
+
when Audio
|
|
23
|
+
value
|
|
24
|
+
when Hash
|
|
25
|
+
Audio.new(**value.symbolize_keys)
|
|
26
|
+
when nil
|
|
27
|
+
nil
|
|
28
|
+
else
|
|
29
|
+
raise ArgumentError, "Cannot cast #{value.class} to Audio"
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
def serialize(value)
|
|
34
|
+
case value
|
|
35
|
+
when Audio
|
|
36
|
+
value.serialize
|
|
37
|
+
when Hash
|
|
38
|
+
value
|
|
39
|
+
when nil
|
|
40
|
+
nil
|
|
41
|
+
else
|
|
42
|
+
raise ArgumentError, "Cannot serialize #{value.class}"
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
def deserialize(value)
|
|
47
|
+
cast(value)
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
# Type for Prediction
|
|
52
|
+
class PredictionType < ActiveModel::Type::Value
|
|
53
|
+
def cast(value)
|
|
54
|
+
case value
|
|
55
|
+
when Prediction
|
|
56
|
+
value
|
|
57
|
+
when Hash
|
|
58
|
+
Prediction.new(**value.symbolize_keys)
|
|
59
|
+
when nil
|
|
60
|
+
nil
|
|
61
|
+
else
|
|
62
|
+
raise ArgumentError, "Cannot cast #{value.class} to Prediction"
|
|
63
|
+
end
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
def serialize(value)
|
|
67
|
+
case value
|
|
68
|
+
when Prediction
|
|
69
|
+
value.serialize
|
|
70
|
+
when Hash
|
|
71
|
+
value
|
|
72
|
+
when nil
|
|
73
|
+
nil
|
|
74
|
+
else
|
|
75
|
+
raise ArgumentError, "Cannot serialize #{value.class}"
|
|
76
|
+
end
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
def deserialize(value)
|
|
80
|
+
cast(value)
|
|
81
|
+
end
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
# Type for ResponseFormat
|
|
85
|
+
class ResponseFormatType < ActiveModel::Type::Value
|
|
86
|
+
def cast(value)
|
|
87
|
+
case value
|
|
88
|
+
when ResponseFormat
|
|
89
|
+
value
|
|
90
|
+
when Hash
|
|
91
|
+
ResponseFormat.new(**value.symbolize_keys)
|
|
92
|
+
when nil
|
|
93
|
+
nil
|
|
94
|
+
else
|
|
95
|
+
raise ArgumentError, "Cannot cast #{value.class} to ResponseFormat"
|
|
96
|
+
end
|
|
97
|
+
end
|
|
98
|
+
|
|
99
|
+
def serialize(value)
|
|
100
|
+
case value
|
|
101
|
+
when ResponseFormat
|
|
102
|
+
value.serialize
|
|
103
|
+
when Hash
|
|
104
|
+
value
|
|
105
|
+
when nil
|
|
106
|
+
nil
|
|
107
|
+
else
|
|
108
|
+
raise ArgumentError, "Cannot serialize #{value.class}"
|
|
109
|
+
end
|
|
110
|
+
end
|
|
111
|
+
|
|
112
|
+
def deserialize(value)
|
|
113
|
+
cast(value)
|
|
114
|
+
end
|
|
115
|
+
end
|
|
116
|
+
|
|
117
|
+
# Type for StreamOptions
|
|
118
|
+
class StreamOptionsType < ActiveModel::Type::Value
|
|
119
|
+
def cast(value)
|
|
120
|
+
case value
|
|
121
|
+
when StreamOptions
|
|
122
|
+
value
|
|
123
|
+
when Hash
|
|
124
|
+
StreamOptions.new(**value.symbolize_keys)
|
|
125
|
+
when nil
|
|
126
|
+
nil
|
|
127
|
+
else
|
|
128
|
+
raise ArgumentError, "Cannot cast #{value.class} to StreamOptions"
|
|
129
|
+
end
|
|
130
|
+
end
|
|
131
|
+
|
|
132
|
+
def serialize(value)
|
|
133
|
+
case value
|
|
134
|
+
when StreamOptions
|
|
135
|
+
value.serialize
|
|
136
|
+
when Hash
|
|
137
|
+
value
|
|
138
|
+
when nil
|
|
139
|
+
nil
|
|
140
|
+
else
|
|
141
|
+
raise ArgumentError, "Cannot serialize #{value.class}"
|
|
142
|
+
end
|
|
143
|
+
end
|
|
144
|
+
|
|
145
|
+
def deserialize(value)
|
|
146
|
+
cast(value)
|
|
147
|
+
end
|
|
148
|
+
end
|
|
149
|
+
|
|
150
|
+
# Type for ToolChoice
|
|
151
|
+
class ToolChoiceType < ActiveModel::Type::Value
|
|
152
|
+
def cast(value)
|
|
153
|
+
case value
|
|
154
|
+
when ToolChoice
|
|
155
|
+
value
|
|
156
|
+
when Hash
|
|
157
|
+
ToolChoice.new(**value.symbolize_keys)
|
|
158
|
+
when String
|
|
159
|
+
ToolChoice.new(mode: value)
|
|
160
|
+
when nil
|
|
161
|
+
nil
|
|
162
|
+
else
|
|
163
|
+
raise ArgumentError, "Cannot cast #{value.class} to ToolChoice"
|
|
164
|
+
end
|
|
165
|
+
end
|
|
166
|
+
|
|
167
|
+
def serialize(value)
|
|
168
|
+
case value
|
|
169
|
+
when ToolChoice
|
|
170
|
+
hash = value.serialize
|
|
171
|
+
# If it's just a mode string, return the string
|
|
172
|
+
if hash[:mode].present? && hash[:type].blank? && hash[:function].blank? && hash[:custom].blank? && hash[:allowed_tools].blank?
|
|
173
|
+
hash[:mode]
|
|
174
|
+
else
|
|
175
|
+
hash
|
|
176
|
+
end
|
|
177
|
+
when Hash
|
|
178
|
+
value
|
|
179
|
+
when String
|
|
180
|
+
value
|
|
181
|
+
when nil
|
|
182
|
+
nil
|
|
183
|
+
else
|
|
184
|
+
raise ArgumentError, "Cannot serialize #{value.class}"
|
|
185
|
+
end
|
|
186
|
+
end
|
|
187
|
+
|
|
188
|
+
def deserialize(value)
|
|
189
|
+
cast(value)
|
|
190
|
+
end
|
|
191
|
+
end
|
|
192
|
+
|
|
193
|
+
# Type for WebSearchOptions
|
|
194
|
+
class WebSearchOptionsType < ActiveModel::Type::Value
|
|
195
|
+
def cast(value)
|
|
196
|
+
case value
|
|
197
|
+
when WebSearchOptions
|
|
198
|
+
value
|
|
199
|
+
when Hash
|
|
200
|
+
WebSearchOptions.new(**value.symbolize_keys)
|
|
201
|
+
when nil
|
|
202
|
+
nil
|
|
203
|
+
else
|
|
204
|
+
raise ArgumentError, "Cannot cast #{value.class} to WebSearchOptions"
|
|
205
|
+
end
|
|
206
|
+
end
|
|
207
|
+
|
|
208
|
+
def serialize(value)
|
|
209
|
+
case value
|
|
210
|
+
when WebSearchOptions
|
|
211
|
+
value.serialize
|
|
212
|
+
when Hash
|
|
213
|
+
value
|
|
214
|
+
when nil
|
|
215
|
+
nil
|
|
216
|
+
else
|
|
217
|
+
raise ArgumentError, "Cannot serialize #{value.class}"
|
|
218
|
+
end
|
|
219
|
+
end
|
|
220
|
+
|
|
221
|
+
def deserialize(value)
|
|
222
|
+
cast(value)
|
|
223
|
+
end
|
|
224
|
+
end
|
|
225
|
+
end
|
|
226
|
+
end
|
|
227
|
+
end
|
|
228
|
+
end
|
|
229
|
+
end
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "active_agent/providers/common/model"
|
|
4
|
+
|
|
5
|
+
module ActiveAgent
|
|
6
|
+
module Providers
|
|
7
|
+
module OpenAI
|
|
8
|
+
module Chat
|
|
9
|
+
module Requests
|
|
10
|
+
class Audio < Common::BaseModel
|
|
11
|
+
# Voice to use for audio output
|
|
12
|
+
attribute :voice, :string
|
|
13
|
+
|
|
14
|
+
# Audio format
|
|
15
|
+
attribute :format, :string
|
|
16
|
+
|
|
17
|
+
validates :voice, inclusion: { in: %w[alloy ash ballad coral echo fable nova onyx sage shimmer] }, allow_nil: true
|
|
18
|
+
validates :format, inclusion: { in: %w[wav mp3 flac opus pcm16] }, allow_nil: true
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
end
|