activeagent 1.0.0.rc1 → 1.0.1
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 +102 -1
- data/lib/active_agent/providers/_base_provider.rb +94 -82
- data/lib/active_agent/providers/anthropic/_types.rb +2 -2
- data/lib/active_agent/providers/anthropic/options.rb +4 -6
- data/lib/active_agent/providers/anthropic/request.rb +157 -78
- data/lib/active_agent/providers/anthropic/transforms.rb +482 -0
- data/lib/active_agent/providers/anthropic_provider.rb +159 -59
- data/lib/active_agent/providers/common/messages/_types.rb +46 -3
- data/lib/active_agent/providers/common/messages/assistant.rb +20 -4
- data/lib/active_agent/providers/common/responses/base.rb +118 -70
- data/lib/active_agent/providers/common/usage.rb +385 -0
- data/lib/active_agent/providers/concerns/instrumentation.rb +263 -0
- data/lib/active_agent/providers/concerns/previewable.rb +39 -5
- data/lib/active_agent/providers/concerns/tool_choice_clearing.rb +62 -0
- data/lib/active_agent/providers/log_subscriber.rb +64 -246
- data/lib/active_agent/providers/mock_provider.rb +23 -23
- data/lib/active_agent/providers/ollama/chat/request.rb +214 -35
- data/lib/active_agent/providers/ollama/chat/transforms.rb +135 -0
- data/lib/active_agent/providers/ollama/embedding/request.rb +160 -47
- data/lib/active_agent/providers/ollama/embedding/transforms.rb +160 -0
- data/lib/active_agent/providers/ollama_provider.rb +0 -1
- data/lib/active_agent/providers/open_ai/_base.rb +3 -2
- data/lib/active_agent/providers/open_ai/chat/_types.rb +13 -1
- data/lib/active_agent/providers/open_ai/chat/request.rb +132 -186
- data/lib/active_agent/providers/open_ai/chat/transforms.rb +444 -0
- data/lib/active_agent/providers/open_ai/chat_provider.rb +95 -36
- data/lib/active_agent/providers/open_ai/embedding/_types.rb +13 -2
- data/lib/active_agent/providers/open_ai/embedding/request.rb +38 -70
- data/lib/active_agent/providers/open_ai/embedding/transforms.rb +88 -0
- data/lib/active_agent/providers/open_ai/responses/_types.rb +1 -7
- data/lib/active_agent/providers/open_ai/responses/request.rb +116 -135
- data/lib/active_agent/providers/open_ai/responses/transforms.rb +363 -0
- data/lib/active_agent/providers/open_ai/responses_provider.rb +115 -30
- data/lib/active_agent/providers/open_ai_provider.rb +0 -3
- data/lib/active_agent/providers/open_router/_types.rb +27 -1
- data/lib/active_agent/providers/open_router/options.rb +49 -1
- data/lib/active_agent/providers/open_router/request.rb +252 -66
- data/lib/active_agent/providers/open_router/requests/_types.rb +0 -1
- data/lib/active_agent/providers/open_router/requests/messages/_types.rb +37 -40
- data/lib/active_agent/providers/open_router/requests/messages/content/file.rb +19 -3
- data/lib/active_agent/providers/open_router/requests/messages/content/files/details.rb +15 -4
- data/lib/active_agent/providers/open_router/requests/plugin.rb +19 -3
- data/lib/active_agent/providers/open_router/requests/plugins/pdf_config.rb +30 -8
- data/lib/active_agent/providers/open_router/requests/prediction.rb +17 -0
- data/lib/active_agent/providers/open_router/requests/provider_preferences/max_price.rb +41 -7
- data/lib/active_agent/providers/open_router/requests/provider_preferences.rb +60 -19
- data/lib/active_agent/providers/open_router/requests/response_format.rb +30 -2
- data/lib/active_agent/providers/open_router/transforms.rb +164 -0
- data/lib/active_agent/providers/open_router_provider.rb +23 -0
- data/lib/active_agent/version.rb +1 -1
- metadata +17 -160
- data/lib/active_agent/generation_provider/open_router/types.rb +0 -505
- data/lib/active_agent/generation_provider/xai_provider.rb +0 -144
- data/lib/active_agent/providers/anthropic/requests/_types.rb +0 -190
- data/lib/active_agent/providers/anthropic/requests/container_params.rb +0 -19
- data/lib/active_agent/providers/anthropic/requests/content/base.rb +0 -21
- data/lib/active_agent/providers/anthropic/requests/content/sources/base.rb +0 -22
- data/lib/active_agent/providers/anthropic/requests/context_management_config.rb +0 -18
- data/lib/active_agent/providers/anthropic/requests/messages/_types.rb +0 -189
- data/lib/active_agent/providers/anthropic/requests/messages/assistant.rb +0 -23
- data/lib/active_agent/providers/anthropic/requests/messages/base.rb +0 -63
- data/lib/active_agent/providers/anthropic/requests/messages/content/_types.rb +0 -143
- data/lib/active_agent/providers/anthropic/requests/messages/content/base.rb +0 -21
- data/lib/active_agent/providers/anthropic/requests/messages/content/document.rb +0 -26
- data/lib/active_agent/providers/anthropic/requests/messages/content/image.rb +0 -23
- data/lib/active_agent/providers/anthropic/requests/messages/content/redacted_thinking.rb +0 -21
- data/lib/active_agent/providers/anthropic/requests/messages/content/search_result.rb +0 -27
- data/lib/active_agent/providers/anthropic/requests/messages/content/sources/_types.rb +0 -171
- data/lib/active_agent/providers/anthropic/requests/messages/content/sources/base.rb +0 -22
- data/lib/active_agent/providers/anthropic/requests/messages/content/sources/document_base64.rb +0 -25
- data/lib/active_agent/providers/anthropic/requests/messages/content/sources/document_file.rb +0 -23
- data/lib/active_agent/providers/anthropic/requests/messages/content/sources/document_text.rb +0 -25
- data/lib/active_agent/providers/anthropic/requests/messages/content/sources/document_url.rb +0 -23
- data/lib/active_agent/providers/anthropic/requests/messages/content/sources/image_base64.rb +0 -27
- data/lib/active_agent/providers/anthropic/requests/messages/content/sources/image_file.rb +0 -23
- data/lib/active_agent/providers/anthropic/requests/messages/content/sources/image_url.rb +0 -23
- data/lib/active_agent/providers/anthropic/requests/messages/content/text.rb +0 -22
- data/lib/active_agent/providers/anthropic/requests/messages/content/thinking.rb +0 -23
- data/lib/active_agent/providers/anthropic/requests/messages/content/tool_result.rb +0 -24
- data/lib/active_agent/providers/anthropic/requests/messages/content/tool_use.rb +0 -28
- data/lib/active_agent/providers/anthropic/requests/messages/user.rb +0 -21
- data/lib/active_agent/providers/anthropic/requests/metadata.rb +0 -18
- data/lib/active_agent/providers/anthropic/requests/response_format.rb +0 -22
- data/lib/active_agent/providers/anthropic/requests/thinking_config/_types.rb +0 -60
- data/lib/active_agent/providers/anthropic/requests/thinking_config/base.rb +0 -20
- data/lib/active_agent/providers/anthropic/requests/thinking_config/disabled.rb +0 -16
- data/lib/active_agent/providers/anthropic/requests/thinking_config/enabled.rb +0 -20
- data/lib/active_agent/providers/anthropic/requests/tool_choice/_types.rb +0 -78
- data/lib/active_agent/providers/anthropic/requests/tool_choice/any.rb +0 -17
- data/lib/active_agent/providers/anthropic/requests/tool_choice/auto.rb +0 -17
- data/lib/active_agent/providers/anthropic/requests/tool_choice/base.rb +0 -20
- data/lib/active_agent/providers/anthropic/requests/tool_choice/none.rb +0 -16
- data/lib/active_agent/providers/anthropic/requests/tool_choice/tool.rb +0 -20
- data/lib/active_agent/providers/ollama/chat/requests/_types.rb +0 -3
- data/lib/active_agent/providers/ollama/chat/requests/messages/_types.rb +0 -116
- data/lib/active_agent/providers/ollama/chat/requests/messages/assistant.rb +0 -19
- data/lib/active_agent/providers/ollama/chat/requests/messages/user.rb +0 -19
- data/lib/active_agent/providers/ollama/embedding/requests/_types.rb +0 -83
- data/lib/active_agent/providers/ollama/embedding/requests/options.rb +0 -104
- data/lib/active_agent/providers/open_ai/chat/requests/_types.rb +0 -229
- data/lib/active_agent/providers/open_ai/chat/requests/audio.rb +0 -24
- data/lib/active_agent/providers/open_ai/chat/requests/messages/_types.rb +0 -123
- data/lib/active_agent/providers/open_ai/chat/requests/messages/assistant.rb +0 -42
- data/lib/active_agent/providers/open_ai/chat/requests/messages/base.rb +0 -78
- data/lib/active_agent/providers/open_ai/chat/requests/messages/content/_types.rb +0 -133
- data/lib/active_agent/providers/open_ai/chat/requests/messages/content/audio.rb +0 -35
- data/lib/active_agent/providers/open_ai/chat/requests/messages/content/base.rb +0 -24
- data/lib/active_agent/providers/open_ai/chat/requests/messages/content/file.rb +0 -26
- data/lib/active_agent/providers/open_ai/chat/requests/messages/content/files/_types.rb +0 -60
- data/lib/active_agent/providers/open_ai/chat/requests/messages/content/files/details.rb +0 -41
- data/lib/active_agent/providers/open_ai/chat/requests/messages/content/image.rb +0 -37
- data/lib/active_agent/providers/open_ai/chat/requests/messages/content/refusal.rb +0 -25
- data/lib/active_agent/providers/open_ai/chat/requests/messages/content/text.rb +0 -25
- data/lib/active_agent/providers/open_ai/chat/requests/messages/developer.rb +0 -25
- data/lib/active_agent/providers/open_ai/chat/requests/messages/function.rb +0 -25
- data/lib/active_agent/providers/open_ai/chat/requests/messages/system.rb +0 -25
- data/lib/active_agent/providers/open_ai/chat/requests/messages/tool.rb +0 -26
- data/lib/active_agent/providers/open_ai/chat/requests/messages/user.rb +0 -32
- data/lib/active_agent/providers/open_ai/chat/requests/prediction.rb +0 -46
- data/lib/active_agent/providers/open_ai/chat/requests/response_format.rb +0 -53
- data/lib/active_agent/providers/open_ai/chat/requests/stream_options.rb +0 -24
- data/lib/active_agent/providers/open_ai/chat/requests/tool_choice.rb +0 -26
- data/lib/active_agent/providers/open_ai/chat/requests/tools/_types.rb +0 -5
- data/lib/active_agent/providers/open_ai/chat/requests/tools/base.rb +0 -22
- data/lib/active_agent/providers/open_ai/chat/requests/tools/custom_tool.rb +0 -41
- data/lib/active_agent/providers/open_ai/chat/requests/tools/function_tool.rb +0 -51
- data/lib/active_agent/providers/open_ai/chat/requests/web_search_options.rb +0 -45
- data/lib/active_agent/providers/open_ai/embedding/requests/_types.rb +0 -49
- data/lib/active_agent/providers/open_ai/responses/requests/_types.rb +0 -231
- data/lib/active_agent/providers/open_ai/responses/requests/conversation.rb +0 -23
- data/lib/active_agent/providers/open_ai/responses/requests/inputs/_types.rb +0 -264
- data/lib/active_agent/providers/open_ai/responses/requests/inputs/assistant_message.rb +0 -22
- data/lib/active_agent/providers/open_ai/responses/requests/inputs/base.rb +0 -89
- data/lib/active_agent/providers/open_ai/responses/requests/inputs/code_interpreter_tool_call.rb +0 -30
- data/lib/active_agent/providers/open_ai/responses/requests/inputs/computer_tool_call.rb +0 -28
- data/lib/active_agent/providers/open_ai/responses/requests/inputs/computer_tool_call_output.rb +0 -33
- data/lib/active_agent/providers/open_ai/responses/requests/inputs/content/_types.rb +0 -207
- data/lib/active_agent/providers/open_ai/responses/requests/inputs/content/base.rb +0 -22
- data/lib/active_agent/providers/open_ai/responses/requests/inputs/content/input_audio.rb +0 -26
- data/lib/active_agent/providers/open_ai/responses/requests/inputs/content/input_file.rb +0 -28
- data/lib/active_agent/providers/open_ai/responses/requests/inputs/content/input_image.rb +0 -28
- data/lib/active_agent/providers/open_ai/responses/requests/inputs/content/input_text.rb +0 -25
- data/lib/active_agent/providers/open_ai/responses/requests/inputs/custom_tool_call.rb +0 -28
- data/lib/active_agent/providers/open_ai/responses/requests/inputs/custom_tool_call_output.rb +0 -27
- data/lib/active_agent/providers/open_ai/responses/requests/inputs/developer_message.rb +0 -20
- data/lib/active_agent/providers/open_ai/responses/requests/inputs/file_search_tool_call.rb +0 -25
- data/lib/active_agent/providers/open_ai/responses/requests/inputs/function_call_output.rb +0 -32
- data/lib/active_agent/providers/open_ai/responses/requests/inputs/function_tool_call.rb +0 -28
- data/lib/active_agent/providers/open_ai/responses/requests/inputs/image_gen_tool_call.rb +0 -27
- data/lib/active_agent/providers/open_ai/responses/requests/inputs/input_message.rb +0 -31
- data/lib/active_agent/providers/open_ai/responses/requests/inputs/item_reference.rb +0 -23
- data/lib/active_agent/providers/open_ai/responses/requests/inputs/local_shell_tool_call.rb +0 -26
- data/lib/active_agent/providers/open_ai/responses/requests/inputs/local_shell_tool_call_output.rb +0 -33
- data/lib/active_agent/providers/open_ai/responses/requests/inputs/mcp_approval_request.rb +0 -30
- data/lib/active_agent/providers/open_ai/responses/requests/inputs/mcp_approval_response.rb +0 -28
- data/lib/active_agent/providers/open_ai/responses/requests/inputs/mcp_list_tools.rb +0 -29
- data/lib/active_agent/providers/open_ai/responses/requests/inputs/mcp_tool_call.rb +0 -35
- data/lib/active_agent/providers/open_ai/responses/requests/inputs/output_message.rb +0 -35
- data/lib/active_agent/providers/open_ai/responses/requests/inputs/reasoning.rb +0 -33
- data/lib/active_agent/providers/open_ai/responses/requests/inputs/system_message.rb +0 -20
- data/lib/active_agent/providers/open_ai/responses/requests/inputs/tool_call_base.rb +0 -27
- data/lib/active_agent/providers/open_ai/responses/requests/inputs/tool_message.rb +0 -23
- data/lib/active_agent/providers/open_ai/responses/requests/inputs/user_message.rb +0 -20
- data/lib/active_agent/providers/open_ai/responses/requests/inputs/web_search_tool_call.rb +0 -24
- data/lib/active_agent/providers/open_ai/responses/requests/prompt_reference.rb +0 -23
- data/lib/active_agent/providers/open_ai/responses/requests/reasoning.rb +0 -23
- data/lib/active_agent/providers/open_ai/responses/requests/stream_options.rb +0 -20
- data/lib/active_agent/providers/open_ai/responses/requests/text/_types.rb +0 -89
- data/lib/active_agent/providers/open_ai/responses/requests/text/base.rb +0 -22
- data/lib/active_agent/providers/open_ai/responses/requests/text/json_object.rb +0 -20
- data/lib/active_agent/providers/open_ai/responses/requests/text/json_schema.rb +0 -48
- data/lib/active_agent/providers/open_ai/responses/requests/text/plain.rb +0 -20
- data/lib/active_agent/providers/open_ai/responses/requests/text.rb +0 -41
- data/lib/active_agent/providers/open_ai/responses/requests/tool_choice.rb +0 -26
- data/lib/active_agent/providers/open_ai/responses/requests/tools/_types.rb +0 -112
- data/lib/active_agent/providers/open_ai/responses/requests/tools/base.rb +0 -25
- data/lib/active_agent/providers/open_ai/responses/requests/tools/code_interpreter_tool.rb +0 -23
- data/lib/active_agent/providers/open_ai/responses/requests/tools/computer_tool.rb +0 -27
- data/lib/active_agent/providers/open_ai/responses/requests/tools/custom_tool.rb +0 -28
- data/lib/active_agent/providers/open_ai/responses/requests/tools/file_search_tool.rb +0 -27
- data/lib/active_agent/providers/open_ai/responses/requests/tools/function_tool.rb +0 -29
- data/lib/active_agent/providers/open_ai/responses/requests/tools/image_generation_tool.rb +0 -37
- data/lib/active_agent/providers/open_ai/responses/requests/tools/local_shell_tool.rb +0 -21
- data/lib/active_agent/providers/open_ai/responses/requests/tools/mcp_tool.rb +0 -41
- data/lib/active_agent/providers/open_ai/responses/requests/tools/web_search_preview_tool.rb +0 -24
- data/lib/active_agent/providers/open_ai/responses/requests/tools/web_search_tool.rb +0 -25
- data/lib/active_agent/providers/open_ai/schema.yml +0 -65937
- data/lib/active_agent/providers/open_router/requests/message.rb +0 -1
- data/lib/active_agent/providers/open_router/requests/messages/assistant.rb +0 -20
- data/lib/active_agent/providers/open_router/requests/messages/user.rb +0 -30
|
@@ -1,14 +1,18 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
require_relative "requests/_types"
|
|
4
3
|
require_relative "request"
|
|
5
4
|
|
|
6
5
|
module ActiveAgent
|
|
7
6
|
module Providers
|
|
8
7
|
module OpenAI
|
|
9
8
|
module Embedding
|
|
10
|
-
#
|
|
9
|
+
# ActiveModel type for casting and serializing embedding requests
|
|
11
10
|
class RequestType < ActiveModel::Type::Value
|
|
11
|
+
# Casts value to Request object
|
|
12
|
+
#
|
|
13
|
+
# @param value [Request, Hash, nil]
|
|
14
|
+
# @return [Request, nil]
|
|
15
|
+
# @raise [ArgumentError] when value cannot be cast
|
|
12
16
|
def cast(value)
|
|
13
17
|
case value
|
|
14
18
|
when Request
|
|
@@ -22,6 +26,11 @@ module ActiveAgent
|
|
|
22
26
|
end
|
|
23
27
|
end
|
|
24
28
|
|
|
29
|
+
# Serializes Request to hash for API submission
|
|
30
|
+
#
|
|
31
|
+
# @param value [Request, Hash, nil]
|
|
32
|
+
# @return [Hash, nil]
|
|
33
|
+
# @raise [ArgumentError] when value cannot be serialized
|
|
25
34
|
def serialize(value)
|
|
26
35
|
case value
|
|
27
36
|
when Request
|
|
@@ -35,6 +44,8 @@ module ActiveAgent
|
|
|
35
44
|
end
|
|
36
45
|
end
|
|
37
46
|
|
|
47
|
+
# @param value [Object]
|
|
48
|
+
# @return [Request, nil]
|
|
38
49
|
def deserialize(value)
|
|
39
50
|
cast(value)
|
|
40
51
|
end
|
|
@@ -1,82 +1,50 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
require "
|
|
4
|
-
require_relative "
|
|
3
|
+
require "json"
|
|
4
|
+
require_relative "transforms"
|
|
5
5
|
|
|
6
6
|
module ActiveAgent
|
|
7
7
|
module Providers
|
|
8
8
|
module OpenAI
|
|
9
9
|
module Embedding
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
#
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
#
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
#
|
|
23
|
-
#
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
#
|
|
27
|
-
#
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
validate :validate_input_format
|
|
41
|
-
validate :validate_input_not_empty
|
|
42
|
-
|
|
43
|
-
private
|
|
44
|
-
|
|
45
|
-
def validate_input_format
|
|
46
|
-
return if input.nil?
|
|
47
|
-
|
|
48
|
-
unless input.is_a?(Array)
|
|
49
|
-
errors.add(:input, "must be stored as an array internally")
|
|
50
|
-
return
|
|
51
|
-
end
|
|
52
|
-
|
|
53
|
-
# Validate array contents
|
|
54
|
-
input.each_with_index do |item, index|
|
|
55
|
-
case item
|
|
56
|
-
when String
|
|
57
|
-
if item.empty?
|
|
58
|
-
errors.add(:input, "cannot contain empty strings at index #{index}")
|
|
59
|
-
end
|
|
60
|
-
when Array
|
|
61
|
-
# Token array validation
|
|
62
|
-
if item.length > 2048
|
|
63
|
-
errors.add(:input, "token arrays must be 2048 dimensions or less at index #{index}")
|
|
64
|
-
end
|
|
65
|
-
if item.empty?
|
|
66
|
-
errors.add(:input, "cannot contain empty token arrays at index #{index}")
|
|
67
|
-
end
|
|
68
|
-
else
|
|
69
|
-
errors.add(:input, "array elements must be strings or token arrays at index #{index}")
|
|
70
|
-
end
|
|
71
|
-
end
|
|
10
|
+
# Wraps OpenAI gem's EmbeddingCreateParams with normalization
|
|
11
|
+
#
|
|
12
|
+
# Delegates to OpenAI::Models::EmbeddingCreateParams while providing
|
|
13
|
+
# parameter normalization via the Transforms module
|
|
14
|
+
class Request < SimpleDelegator
|
|
15
|
+
# Default parameter values applied during initialization
|
|
16
|
+
DEFAULTS = {}.freeze
|
|
17
|
+
|
|
18
|
+
# Creates a new embedding request
|
|
19
|
+
#
|
|
20
|
+
# @param params [Hash] embedding parameters
|
|
21
|
+
# @option params [String, Array<String>, Array<Integer>, Array<Array<Integer>>] :input
|
|
22
|
+
# text or token array(s) to embed
|
|
23
|
+
# @option params [String] :model embedding model identifier
|
|
24
|
+
# @option params [Integer, nil] :dimensions number of dimensions for output (text-embedding-3 only)
|
|
25
|
+
# @option params [String, nil] :encoding_format "float" or "base64"
|
|
26
|
+
# @option params [String, nil] :user unique user identifier
|
|
27
|
+
# @raise [ArgumentError] when parameters are invalid
|
|
28
|
+
def initialize(**params)
|
|
29
|
+
# Step 1: Normalize parameters
|
|
30
|
+
params = Transforms.normalize_params(params)
|
|
31
|
+
|
|
32
|
+
# Step 2: Create gem model - this validates all parameters!
|
|
33
|
+
gem_model = ::OpenAI::Models::EmbeddingCreateParams.new(**params)
|
|
34
|
+
|
|
35
|
+
# Step 3: Delegate all method calls to gem model
|
|
36
|
+
super(gem_model)
|
|
37
|
+
rescue ArgumentError => e
|
|
38
|
+
# Re-raise with more context
|
|
39
|
+
raise ArgumentError, "Invalid OpenAI Embedding request parameters: #{e.message}"
|
|
72
40
|
end
|
|
73
41
|
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
42
|
+
# Serializes request for API submission
|
|
43
|
+
#
|
|
44
|
+
# @return [Hash] cleaned request hash without nil values
|
|
45
|
+
def serialize
|
|
46
|
+
serialized = Transforms.gem_to_hash(__getobj__)
|
|
47
|
+
Transforms.cleanup_serialized_request(serialized, DEFAULTS, __getobj__)
|
|
80
48
|
end
|
|
81
49
|
end
|
|
82
50
|
end
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module ActiveAgent
|
|
4
|
+
module Providers
|
|
5
|
+
module OpenAI
|
|
6
|
+
# Handles transformation and normalization of embedding request parameters
|
|
7
|
+
# for the OpenAI Embeddings API
|
|
8
|
+
module Embedding
|
|
9
|
+
# Provides transformation methods for normalizing embedding parameters
|
|
10
|
+
# to OpenAI gem's native format
|
|
11
|
+
module Transforms
|
|
12
|
+
# Converts OpenAI gem objects to hash representation
|
|
13
|
+
#
|
|
14
|
+
# @param obj [Object] gem object or primitive value
|
|
15
|
+
# @return [Hash, Object] hash if object supports JSON serialization, otherwise original object
|
|
16
|
+
def self.gem_to_hash(obj)
|
|
17
|
+
if obj.respond_to?(:to_json)
|
|
18
|
+
JSON.parse(obj.to_json)
|
|
19
|
+
else
|
|
20
|
+
obj
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
# Normalizes all embedding request parameters
|
|
25
|
+
#
|
|
26
|
+
# @param params [Hash] raw request parameters
|
|
27
|
+
# @return [Hash] normalized parameters
|
|
28
|
+
def self.normalize_params(params)
|
|
29
|
+
normalized = params.dup
|
|
30
|
+
|
|
31
|
+
if normalized[:input]
|
|
32
|
+
normalized[:input] = normalize_input(normalized[:input])
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
normalized
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
# Normalizes input parameter to supported format
|
|
39
|
+
#
|
|
40
|
+
# Handles multiple input formats:
|
|
41
|
+
# - `"text"` - single string for one embedding
|
|
42
|
+
# - `["text1", "text2"]` - array of strings for multiple embeddings
|
|
43
|
+
# - `[1, 2, 3]` - token array for single embedding
|
|
44
|
+
# - `[[1, 2], [3, 4]]` - array of token arrays for multiple embeddings
|
|
45
|
+
#
|
|
46
|
+
# @param input [String, Array<String>, Array<Integer>, Array<Array<Integer>>]
|
|
47
|
+
# @return [String, Array] normalized input in gem-compatible format
|
|
48
|
+
def self.normalize_input(input)
|
|
49
|
+
case input
|
|
50
|
+
when String
|
|
51
|
+
input
|
|
52
|
+
when Array
|
|
53
|
+
if input.empty?
|
|
54
|
+
input
|
|
55
|
+
elsif input.first.is_a?(Integer)
|
|
56
|
+
input
|
|
57
|
+
elsif input.first.is_a?(Array)
|
|
58
|
+
input
|
|
59
|
+
else
|
|
60
|
+
input
|
|
61
|
+
end
|
|
62
|
+
else
|
|
63
|
+
input
|
|
64
|
+
end
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
# Removes nil values from serialized request
|
|
68
|
+
#
|
|
69
|
+
# @param serialized [Hash] serialized request
|
|
70
|
+
# @param defaults [Hash] default values to remove
|
|
71
|
+
# @param gem_object [Object] original gem object (unused but for consistency)
|
|
72
|
+
# @return [Hash] cleaned request hash
|
|
73
|
+
def self.cleanup_serialized_request(serialized, defaults = {}, gem_object = nil)
|
|
74
|
+
# Remove nil values
|
|
75
|
+
cleaned = serialized.compact
|
|
76
|
+
|
|
77
|
+
# Remove default values
|
|
78
|
+
defaults.each do |key, value|
|
|
79
|
+
cleaned.delete(key) if cleaned[key] == value
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
cleaned
|
|
83
|
+
end
|
|
84
|
+
end
|
|
85
|
+
end
|
|
86
|
+
end
|
|
87
|
+
end
|
|
88
|
+
end
|
|
@@ -24,13 +24,7 @@ module ActiveAgent
|
|
|
24
24
|
def serialize(value)
|
|
25
25
|
case value
|
|
26
26
|
when Request
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
if hash[:input] in [ { role: "user", content: String } ]
|
|
30
|
-
hash[:input] = hash[:input][0][:content]
|
|
31
|
-
end
|
|
32
|
-
|
|
33
|
-
hash
|
|
27
|
+
value.serialize
|
|
34
28
|
when Hash
|
|
35
29
|
value
|
|
36
30
|
when nil
|
|
@@ -1,160 +1,141 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
require_relative "requests/_types"
|
|
3
|
+
require_relative "transforms"
|
|
5
4
|
|
|
6
5
|
module ActiveAgent
|
|
7
6
|
module Providers
|
|
8
7
|
module OpenAI
|
|
9
8
|
module Responses
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
#
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
#
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
#
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
#
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
#
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
#
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
#
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
# Streaming
|
|
61
|
-
attribute :stream, :boolean, default: false
|
|
62
|
-
attribute :stream_options, Requests::StreamOptionsType.new
|
|
63
|
-
|
|
64
|
-
# Temperature sampling
|
|
65
|
-
attribute :temperature, :float, default: 1
|
|
66
|
-
|
|
67
|
-
# Text response configuration
|
|
68
|
-
attribute :text, Requests::TextType.new
|
|
69
|
-
|
|
70
|
-
# Tool choice
|
|
71
|
-
attribute :tool_choice, Requests::ToolChoiceType.new
|
|
72
|
-
|
|
73
|
-
# Tools array
|
|
74
|
-
attribute :tools, Requests::Tools::ToolsType.new
|
|
75
|
-
|
|
76
|
-
# Top logprobs
|
|
77
|
-
attribute :top_logprobs, :integer
|
|
78
|
-
|
|
79
|
-
# Top P sampling
|
|
80
|
-
attribute :top_p, :float, default: 1
|
|
81
|
-
|
|
82
|
-
# Truncation strategy
|
|
83
|
-
attribute :truncation, :string, default: "disabled"
|
|
9
|
+
# Wraps OpenAI gem's ResponseCreateParams with field mapping and normalization
|
|
10
|
+
#
|
|
11
|
+
# Delegates to OpenAI::Models::Responses::ResponseCreateParams while providing
|
|
12
|
+
# compatibility layer for common format fields and content normalization:
|
|
13
|
+
# - `messages` → `input`
|
|
14
|
+
# - `response_format` → `text` (via ResponseTextConfig)
|
|
15
|
+
# - Instructions array joined to string
|
|
16
|
+
class Request < SimpleDelegator
|
|
17
|
+
# Default parameter values applied during initialization
|
|
18
|
+
DEFAULTS = {
|
|
19
|
+
service_tier: "auto",
|
|
20
|
+
store: true,
|
|
21
|
+
temperature: 1.0,
|
|
22
|
+
top_p: 1.0,
|
|
23
|
+
truncation: "disabled",
|
|
24
|
+
parallel_tool_calls: true,
|
|
25
|
+
background: false,
|
|
26
|
+
include: []
|
|
27
|
+
}.freeze
|
|
28
|
+
|
|
29
|
+
# @return [Boolean, nil]
|
|
30
|
+
attr_reader :stream
|
|
31
|
+
|
|
32
|
+
# @return [Hash, nil]
|
|
33
|
+
attr_reader :response_format
|
|
34
|
+
|
|
35
|
+
# Creates a new response creation request
|
|
36
|
+
#
|
|
37
|
+
# Maps common format fields to Responses API format:
|
|
38
|
+
# - `messages` → `input`
|
|
39
|
+
# - `response_format` → `text` parameter
|
|
40
|
+
# - Instructions array → joined string
|
|
41
|
+
#
|
|
42
|
+
# @param params [Hash] request parameters
|
|
43
|
+
# @option params [String] :model required model identifier
|
|
44
|
+
# @option params [Array, String, Hash] :input messages or content
|
|
45
|
+
# @option params [Array, String, Hash] :messages alternative to :input (mapped automatically)
|
|
46
|
+
# @option params [Hash, String, Symbol] :response_format
|
|
47
|
+
# @option params [Array<String>, String] :instructions
|
|
48
|
+
# @option params [Integer] :max_output_tokens
|
|
49
|
+
# @raise [ArgumentError] when parameters are invalid
|
|
50
|
+
def initialize(**params)
|
|
51
|
+
# Step 1: Extract custom fields
|
|
52
|
+
@stream = params[:stream]
|
|
53
|
+
@response_format = params.delete(:response_format)
|
|
54
|
+
|
|
55
|
+
# Step 2: Map common format 'messages' to OpenAI Responses 'input'
|
|
56
|
+
if params.key?(:messages)
|
|
57
|
+
params[:input] = params.delete(:messages)
|
|
58
|
+
end
|
|
84
59
|
|
|
85
|
-
|
|
86
|
-
|
|
60
|
+
# Step 3: Join instructions array into string (like Chat API)
|
|
61
|
+
if params[:instructions].is_a?(Array)
|
|
62
|
+
params[:instructions] = params[:instructions].join("\n")
|
|
63
|
+
end
|
|
87
64
|
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
validates :top_p, numericality: { greater_than_or_equal_to: 0, less_than_or_equal_to: 1 }, allow_nil: true
|
|
93
|
-
validates :top_logprobs, numericality: { greater_than_or_equal_to: 0, less_than_or_equal_to: 20 }, allow_nil: true
|
|
94
|
-
validates :service_tier, inclusion: { in: %w[auto default flex priority] }, allow_nil: true
|
|
95
|
-
validates :truncation, inclusion: { in: %w[auto disabled] }, allow_nil: true
|
|
65
|
+
# Step 4: Map response_format to text parameter for Responses API
|
|
66
|
+
if @response_format
|
|
67
|
+
params[:text] = Responses::Transforms.normalize_response_format(@response_format)
|
|
68
|
+
end
|
|
96
69
|
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
70
|
+
# Step 5: Apply defaults
|
|
71
|
+
params = apply_defaults(params)
|
|
72
|
+
|
|
73
|
+
# Step 6: Normalize input content for gem compatibility
|
|
74
|
+
params[:input] = Responses::Transforms.normalize_input(params[:input]) if params[:input]
|
|
75
|
+
|
|
76
|
+
# Step 7: Normalize tools and tool_choice from common format
|
|
77
|
+
params[:tools] = Responses::Transforms.normalize_tools(params[:tools]) if params[:tools]
|
|
78
|
+
params[:tool_choice] = Responses::Transforms.normalize_tool_choice(params[:tool_choice]) if params[:tool_choice]
|
|
79
|
+
|
|
80
|
+
# Step 8: Normalize MCP servers from common format (mcps parameter)
|
|
81
|
+
# OpenAI treats MCP servers as a special type of tool in the tools array
|
|
82
|
+
mcp_param = params[:mcps] || params[:mcp_servers]
|
|
83
|
+
if mcp_param&.any?
|
|
84
|
+
normalized_mcp_tools = Responses::Transforms.normalize_mcp_servers(mcp_param)
|
|
85
|
+
params.delete(:mcps)
|
|
86
|
+
params.delete(:mcp_servers)
|
|
87
|
+
# Merge MCP servers into tools array
|
|
88
|
+
params[:tools] = (params[:tools] || []) + normalized_mcp_tools
|
|
89
|
+
end
|
|
100
90
|
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
alias_attribute :message, :input
|
|
104
|
-
alias_attribute :response_format, :text
|
|
91
|
+
# Step 9: Create gem model - delegates to OpenAI gem
|
|
92
|
+
gem_model = ::OpenAI::Models::Responses::ResponseCreateParams.new(**params)
|
|
105
93
|
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
94
|
+
# Step 10: Delegate all method calls to gem model
|
|
95
|
+
super(gem_model)
|
|
96
|
+
rescue ArgumentError => e
|
|
97
|
+
# Re-raise with more context
|
|
98
|
+
raise ArgumentError, "Invalid OpenAI Responses request parameters: #{e.message}"
|
|
109
99
|
end
|
|
110
100
|
|
|
111
|
-
|
|
101
|
+
# Serializes request for API call
|
|
102
|
+
#
|
|
103
|
+
# Uses gem's JSON serialization and delegates cleanup to Transforms module.
|
|
104
|
+
#
|
|
105
|
+
# @return [Hash] cleaned request hash
|
|
106
|
+
def serialize
|
|
107
|
+
hash = Responses::Transforms.gem_to_hash(__getobj__)
|
|
108
|
+
Responses::Transforms.cleanup_serialized_request(hash, DEFAULTS, __getobj__)
|
|
109
|
+
end
|
|
112
110
|
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
end
|
|
111
|
+
# @return [Array, String, Hash, nil]
|
|
112
|
+
def messages
|
|
113
|
+
__getobj__.instance_variable_get(:@data)[:input]
|
|
117
114
|
end
|
|
118
115
|
|
|
119
|
-
|
|
120
|
-
|
|
116
|
+
# Sets input messages with normalization
|
|
117
|
+
#
|
|
118
|
+
# @param value [Array, String, Hash]
|
|
119
|
+
# @return [void]
|
|
120
|
+
def messages=(value)
|
|
121
|
+
normalized_value = Responses::Transforms.normalize_input(value)
|
|
122
|
+
__getobj__.instance_variable_get(:@data)[:input] = normalized_value
|
|
123
|
+
end
|
|
121
124
|
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
return
|
|
125
|
-
end
|
|
125
|
+
alias_method :message, :messages
|
|
126
|
+
alias_method :message=, :messages=
|
|
126
127
|
|
|
127
|
-
|
|
128
|
-
if key.to_s.length > 64
|
|
129
|
-
errors.add(:metadata, "keys must be 64 characters or less")
|
|
130
|
-
end
|
|
131
|
-
if value.to_s.length > 512
|
|
132
|
-
errors.add(:metadata, "values must be 512 characters or less")
|
|
133
|
-
end
|
|
134
|
-
end
|
|
128
|
+
private
|
|
135
129
|
|
|
136
|
-
|
|
137
|
-
|
|
130
|
+
# @api private
|
|
131
|
+
# @param params [Hash]
|
|
132
|
+
# @return [Hash]
|
|
133
|
+
def apply_defaults(params)
|
|
134
|
+
DEFAULTS.each do |key, value|
|
|
135
|
+
params[key] = value unless params.key?(key)
|
|
138
136
|
end
|
|
139
|
-
end
|
|
140
137
|
|
|
141
|
-
|
|
142
|
-
return if include.nil? || include.empty?
|
|
143
|
-
|
|
144
|
-
valid_include_values = [
|
|
145
|
-
"web_search_call.action.sources",
|
|
146
|
-
"code_interpreter_call.outputs",
|
|
147
|
-
"computer_call_output.output.image_url",
|
|
148
|
-
"file_search_call.results",
|
|
149
|
-
"message.input_image.image_url",
|
|
150
|
-
"message.output_text.logprobs",
|
|
151
|
-
"reasoning.encrypted_content"
|
|
152
|
-
]
|
|
153
|
-
|
|
154
|
-
invalid_values = include - valid_include_values
|
|
155
|
-
if invalid_values.any?
|
|
156
|
-
errors.add(:include, "contains invalid values: #{invalid_values.join(', ')}")
|
|
157
|
-
end
|
|
138
|
+
params
|
|
158
139
|
end
|
|
159
140
|
end
|
|
160
141
|
end
|