swarm_sdk 2.7.13 → 3.0.0.alpha1
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/lib/swarm_sdk/ruby_llm_patches/chat_callbacks_patch.rb +43 -22
- data/lib/swarm_sdk/ruby_llm_patches/init.rb +6 -0
- data/lib/swarm_sdk/ruby_llm_patches/mcp_ssl_patch.rb +144 -0
- data/lib/swarm_sdk/ruby_llm_patches/tool_concurrency_patch.rb +3 -4
- data/lib/swarm_sdk/v3/agent.rb +1165 -0
- data/lib/swarm_sdk/v3/agent_builder.rb +533 -0
- data/lib/swarm_sdk/v3/agent_definition.rb +330 -0
- data/lib/swarm_sdk/v3/configuration.rb +490 -0
- data/lib/swarm_sdk/v3/debug_log.rb +86 -0
- data/lib/swarm_sdk/v3/event_stream.rb +130 -0
- data/lib/swarm_sdk/v3/hooks/context.rb +112 -0
- data/lib/swarm_sdk/v3/hooks/result.rb +115 -0
- data/lib/swarm_sdk/v3/hooks/runner.rb +128 -0
- data/lib/swarm_sdk/v3/mcp/connector.rb +183 -0
- data/lib/swarm_sdk/v3/mcp/mcp_error.rb +15 -0
- data/lib/swarm_sdk/v3/mcp/server_definition.rb +125 -0
- data/lib/swarm_sdk/v3/mcp/ssl_http_transport.rb +103 -0
- data/lib/swarm_sdk/v3/mcp/stdio_transport.rb +135 -0
- data/lib/swarm_sdk/v3/mcp/tool_proxy.rb +53 -0
- data/lib/swarm_sdk/v3/memory/adapters/base.rb +297 -0
- data/lib/swarm_sdk/v3/memory/adapters/faiss_support.rb +194 -0
- data/lib/swarm_sdk/v3/memory/adapters/filesystem_adapter.rb +212 -0
- data/lib/swarm_sdk/v3/memory/adapters/sqlite_adapter.rb +507 -0
- data/lib/swarm_sdk/v3/memory/adapters/vector_utils.rb +88 -0
- data/lib/swarm_sdk/v3/memory/card.rb +206 -0
- data/lib/swarm_sdk/v3/memory/cluster.rb +146 -0
- data/lib/swarm_sdk/v3/memory/compressor.rb +496 -0
- data/lib/swarm_sdk/v3/memory/consolidator.rb +427 -0
- data/lib/swarm_sdk/v3/memory/context_builder.rb +339 -0
- data/lib/swarm_sdk/v3/memory/edge.rb +105 -0
- data/lib/swarm_sdk/v3/memory/embedder.rb +185 -0
- data/lib/swarm_sdk/v3/memory/exposure_tracker.rb +104 -0
- data/lib/swarm_sdk/v3/memory/ingestion_pipeline.rb +394 -0
- data/lib/swarm_sdk/v3/memory/retriever.rb +289 -0
- data/lib/swarm_sdk/v3/memory/store.rb +489 -0
- data/lib/swarm_sdk/v3/skills/loader.rb +147 -0
- data/lib/swarm_sdk/v3/skills/manifest.rb +45 -0
- data/lib/swarm_sdk/v3/sub_task_agent.rb +248 -0
- data/lib/swarm_sdk/v3/tools/base.rb +80 -0
- data/lib/swarm_sdk/v3/tools/bash.rb +174 -0
- data/lib/swarm_sdk/v3/tools/clock.rb +32 -0
- data/lib/swarm_sdk/v3/tools/edit.rb +111 -0
- data/lib/swarm_sdk/v3/tools/glob.rb +96 -0
- data/lib/swarm_sdk/v3/tools/grep.rb +200 -0
- data/lib/swarm_sdk/v3/tools/message_teammate.rb +15 -0
- data/lib/swarm_sdk/v3/tools/message_user.rb +15 -0
- data/lib/swarm_sdk/v3/tools/read.rb +181 -0
- data/lib/swarm_sdk/v3/tools/read_tracker.rb +40 -0
- data/lib/swarm_sdk/v3/tools/registry.rb +208 -0
- data/lib/swarm_sdk/v3/tools/sub_task.rb +183 -0
- data/lib/swarm_sdk/v3/tools/think.rb +88 -0
- data/lib/swarm_sdk/v3/tools/write.rb +87 -0
- data/lib/swarm_sdk/v3.rb +145 -0
- metadata +84 -148
- data/lib/swarm_sdk/agent/RETRY_LOGIC.md +0 -175
- data/lib/swarm_sdk/agent/builder.rb +0 -680
- data/lib/swarm_sdk/agent/chat.rb +0 -1432
- data/lib/swarm_sdk/agent/chat_helpers/context_tracker.rb +0 -375
- data/lib/swarm_sdk/agent/chat_helpers/event_emitter.rb +0 -204
- data/lib/swarm_sdk/agent/chat_helpers/hook_integration.rb +0 -480
- data/lib/swarm_sdk/agent/chat_helpers/instrumentation.rb +0 -85
- data/lib/swarm_sdk/agent/chat_helpers/llm_configuration.rb +0 -290
- data/lib/swarm_sdk/agent/chat_helpers/logging_helpers.rb +0 -116
- data/lib/swarm_sdk/agent/chat_helpers/serialization.rb +0 -83
- data/lib/swarm_sdk/agent/chat_helpers/system_reminder_injector.rb +0 -134
- data/lib/swarm_sdk/agent/chat_helpers/system_reminders.rb +0 -79
- data/lib/swarm_sdk/agent/chat_helpers/token_tracking.rb +0 -146
- data/lib/swarm_sdk/agent/context.rb +0 -115
- data/lib/swarm_sdk/agent/context_manager.rb +0 -315
- data/lib/swarm_sdk/agent/definition.rb +0 -581
- data/lib/swarm_sdk/agent/llm_instrumentation_middleware.rb +0 -226
- data/lib/swarm_sdk/agent/system_prompt_builder.rb +0 -161
- data/lib/swarm_sdk/agent/tool_registry.rb +0 -189
- data/lib/swarm_sdk/agent_registry.rb +0 -146
- data/lib/swarm_sdk/builders/base_builder.rb +0 -553
- data/lib/swarm_sdk/claude_code_agent_adapter.rb +0 -205
- data/lib/swarm_sdk/concerns/cleanupable.rb +0 -39
- data/lib/swarm_sdk/concerns/snapshotable.rb +0 -67
- data/lib/swarm_sdk/concerns/validatable.rb +0 -55
- data/lib/swarm_sdk/config.rb +0 -367
- data/lib/swarm_sdk/configuration/parser.rb +0 -397
- data/lib/swarm_sdk/configuration/translator.rb +0 -283
- data/lib/swarm_sdk/configuration.rb +0 -165
- data/lib/swarm_sdk/context_compactor/metrics.rb +0 -147
- data/lib/swarm_sdk/context_compactor/token_counter.rb +0 -102
- data/lib/swarm_sdk/context_compactor.rb +0 -335
- data/lib/swarm_sdk/context_management/builder.rb +0 -128
- data/lib/swarm_sdk/context_management/context.rb +0 -328
- data/lib/swarm_sdk/custom_tool_registry.rb +0 -226
- data/lib/swarm_sdk/defaults.rb +0 -251
- data/lib/swarm_sdk/events_to_messages.rb +0 -199
- data/lib/swarm_sdk/hooks/adapter.rb +0 -359
- data/lib/swarm_sdk/hooks/context.rb +0 -197
- data/lib/swarm_sdk/hooks/definition.rb +0 -80
- data/lib/swarm_sdk/hooks/error.rb +0 -29
- data/lib/swarm_sdk/hooks/executor.rb +0 -146
- data/lib/swarm_sdk/hooks/registry.rb +0 -147
- data/lib/swarm_sdk/hooks/result.rb +0 -150
- data/lib/swarm_sdk/hooks/shell_executor.rb +0 -256
- data/lib/swarm_sdk/hooks/tool_call.rb +0 -35
- data/lib/swarm_sdk/hooks/tool_result.rb +0 -62
- data/lib/swarm_sdk/log_collector.rb +0 -227
- data/lib/swarm_sdk/log_stream.rb +0 -127
- data/lib/swarm_sdk/markdown_parser.rb +0 -75
- data/lib/swarm_sdk/model_aliases.json +0 -8
- data/lib/swarm_sdk/models.json +0 -44002
- data/lib/swarm_sdk/models.rb +0 -161
- data/lib/swarm_sdk/node_context.rb +0 -245
- data/lib/swarm_sdk/observer/builder.rb +0 -81
- data/lib/swarm_sdk/observer/config.rb +0 -45
- data/lib/swarm_sdk/observer/manager.rb +0 -236
- data/lib/swarm_sdk/patterns/agent_observer.rb +0 -160
- data/lib/swarm_sdk/permissions/config.rb +0 -239
- data/lib/swarm_sdk/permissions/error_formatter.rb +0 -121
- data/lib/swarm_sdk/permissions/path_matcher.rb +0 -35
- data/lib/swarm_sdk/permissions/validator.rb +0 -173
- data/lib/swarm_sdk/permissions_builder.rb +0 -122
- data/lib/swarm_sdk/plugin.rb +0 -309
- data/lib/swarm_sdk/plugin_registry.rb +0 -101
- data/lib/swarm_sdk/proc_helpers.rb +0 -53
- data/lib/swarm_sdk/prompts/base_system_prompt.md.erb +0 -117
- data/lib/swarm_sdk/restore_result.rb +0 -65
- data/lib/swarm_sdk/result.rb +0 -212
- data/lib/swarm_sdk/snapshot.rb +0 -156
- data/lib/swarm_sdk/snapshot_from_events.rb +0 -397
- data/lib/swarm_sdk/state_restorer.rb +0 -476
- data/lib/swarm_sdk/state_snapshot.rb +0 -334
- data/lib/swarm_sdk/swarm/agent_initializer.rb +0 -648
- data/lib/swarm_sdk/swarm/all_agents_builder.rb +0 -195
- data/lib/swarm_sdk/swarm/builder.rb +0 -256
- data/lib/swarm_sdk/swarm/executor.rb +0 -290
- data/lib/swarm_sdk/swarm/hook_triggers.rb +0 -151
- data/lib/swarm_sdk/swarm/lazy_delegate_chat.rb +0 -372
- data/lib/swarm_sdk/swarm/logging_callbacks.rb +0 -360
- data/lib/swarm_sdk/swarm/mcp_configurator.rb +0 -270
- data/lib/swarm_sdk/swarm/swarm_registry_builder.rb +0 -67
- data/lib/swarm_sdk/swarm/tool_configurator.rb +0 -392
- data/lib/swarm_sdk/swarm.rb +0 -843
- data/lib/swarm_sdk/swarm_loader.rb +0 -145
- data/lib/swarm_sdk/swarm_registry.rb +0 -136
- data/lib/swarm_sdk/tools/base.rb +0 -63
- data/lib/swarm_sdk/tools/bash.rb +0 -280
- data/lib/swarm_sdk/tools/clock.rb +0 -46
- data/lib/swarm_sdk/tools/delegate.rb +0 -389
- data/lib/swarm_sdk/tools/document_converters/base_converter.rb +0 -83
- data/lib/swarm_sdk/tools/document_converters/docx_converter.rb +0 -99
- data/lib/swarm_sdk/tools/document_converters/html_converter.rb +0 -101
- data/lib/swarm_sdk/tools/document_converters/pdf_converter.rb +0 -78
- data/lib/swarm_sdk/tools/document_converters/xlsx_converter.rb +0 -194
- data/lib/swarm_sdk/tools/edit.rb +0 -145
- data/lib/swarm_sdk/tools/glob.rb +0 -166
- data/lib/swarm_sdk/tools/grep.rb +0 -235
- data/lib/swarm_sdk/tools/image_extractors/docx_image_extractor.rb +0 -43
- data/lib/swarm_sdk/tools/image_extractors/pdf_image_extractor.rb +0 -167
- data/lib/swarm_sdk/tools/image_formats/tiff_builder.rb +0 -65
- data/lib/swarm_sdk/tools/mcp_tool_stub.rb +0 -198
- data/lib/swarm_sdk/tools/multi_edit.rb +0 -236
- data/lib/swarm_sdk/tools/path_resolver.rb +0 -92
- data/lib/swarm_sdk/tools/read.rb +0 -261
- data/lib/swarm_sdk/tools/registry.rb +0 -205
- data/lib/swarm_sdk/tools/scratchpad/scratchpad_list.rb +0 -117
- data/lib/swarm_sdk/tools/scratchpad/scratchpad_read.rb +0 -97
- data/lib/swarm_sdk/tools/scratchpad/scratchpad_write.rb +0 -108
- data/lib/swarm_sdk/tools/stores/read_tracker.rb +0 -96
- data/lib/swarm_sdk/tools/stores/scratchpad_storage.rb +0 -273
- data/lib/swarm_sdk/tools/stores/storage.rb +0 -142
- data/lib/swarm_sdk/tools/stores/todo_manager.rb +0 -65
- data/lib/swarm_sdk/tools/think.rb +0 -100
- data/lib/swarm_sdk/tools/todo_write.rb +0 -237
- data/lib/swarm_sdk/tools/web_fetch.rb +0 -264
- data/lib/swarm_sdk/tools/write.rb +0 -112
- data/lib/swarm_sdk/transcript_builder.rb +0 -278
- data/lib/swarm_sdk/utils.rb +0 -68
- data/lib/swarm_sdk/validation_result.rb +0 -33
- data/lib/swarm_sdk/version.rb +0 -5
- data/lib/swarm_sdk/workflow/agent_config.rb +0 -95
- data/lib/swarm_sdk/workflow/builder.rb +0 -227
- data/lib/swarm_sdk/workflow/executor.rb +0 -497
- data/lib/swarm_sdk/workflow/node_builder.rb +0 -593
- data/lib/swarm_sdk/workflow/transformer_executor.rb +0 -250
- data/lib/swarm_sdk/workflow.rb +0 -589
- data/lib/swarm_sdk.rb +0 -718
|
@@ -0,0 +1,330 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module SwarmSDK
|
|
4
|
+
module V3
|
|
5
|
+
# Immutable agent configuration
|
|
6
|
+
#
|
|
7
|
+
# Defines everything about an agent's identity, capabilities, and memory settings.
|
|
8
|
+
# Once created, a definition cannot be modified — create a new one instead.
|
|
9
|
+
#
|
|
10
|
+
# @example Minimal definition
|
|
11
|
+
# definition = AgentDefinition.new(
|
|
12
|
+
# name: :assistant,
|
|
13
|
+
# description: "A helpful assistant",
|
|
14
|
+
# )
|
|
15
|
+
#
|
|
16
|
+
# @example Full definition with memory
|
|
17
|
+
# definition = AgentDefinition.new(
|
|
18
|
+
# name: :researcher,
|
|
19
|
+
# description: "Research specialist",
|
|
20
|
+
# model: "claude-sonnet-4",
|
|
21
|
+
# system_prompt: "You are an expert researcher.",
|
|
22
|
+
# tools: [:Read, :Write, :Edit, :Bash, :Grep, :Glob],
|
|
23
|
+
# directory: "/path/to/project",
|
|
24
|
+
# parameters: { temperature: 0.7, thinking: { type: "enabled", budget_tokens: 10_000 } },
|
|
25
|
+
# headers: { "anthropic-beta" => "some-feature" },
|
|
26
|
+
# memory_directory: ".swarm/memory",
|
|
27
|
+
# memory_stm_turns: 8,
|
|
28
|
+
# memory_retrieval_top_k: 15,
|
|
29
|
+
# )
|
|
30
|
+
#
|
|
31
|
+
# @example Custom memory adapter
|
|
32
|
+
# definition = AgentDefinition.new(
|
|
33
|
+
# name: :assistant,
|
|
34
|
+
# description: "Assistant with Postgres memory",
|
|
35
|
+
# memory_adapter: PgvectorAdapter.new("postgres://localhost/myapp"),
|
|
36
|
+
# )
|
|
37
|
+
class AgentDefinition
|
|
38
|
+
# Valid API versions for OpenAI provider
|
|
39
|
+
VALID_API_VERSIONS = ["v1/responses", "v1/chat/completions"].freeze
|
|
40
|
+
|
|
41
|
+
# Valid queue delivery modes
|
|
42
|
+
VALID_QUEUE_MODES = [:all, :one_at_a_time].freeze
|
|
43
|
+
|
|
44
|
+
# @return [Symbol] Agent identifier
|
|
45
|
+
attr_reader :name
|
|
46
|
+
|
|
47
|
+
# @return [String] Agent role description
|
|
48
|
+
attr_reader :description
|
|
49
|
+
|
|
50
|
+
# @return [String] LLM model ID
|
|
51
|
+
attr_reader :model
|
|
52
|
+
|
|
53
|
+
# @return [String, nil] LLM provider
|
|
54
|
+
attr_reader :provider
|
|
55
|
+
|
|
56
|
+
# @return [String, nil] System prompt instructions
|
|
57
|
+
attr_reader :system_prompt
|
|
58
|
+
|
|
59
|
+
# @return [Array<Symbol>] Tool names
|
|
60
|
+
attr_reader :tools
|
|
61
|
+
|
|
62
|
+
# @return [String] Working directory
|
|
63
|
+
attr_reader :directory
|
|
64
|
+
|
|
65
|
+
# @return [String, nil] Custom API endpoint
|
|
66
|
+
attr_reader :base_url
|
|
67
|
+
|
|
68
|
+
# @return [Integer, nil] Maximum concurrent tool executions
|
|
69
|
+
attr_reader :max_concurrent_tools
|
|
70
|
+
|
|
71
|
+
# @return [Hash] Raw API body parameters (temperature, thinking, etc.)
|
|
72
|
+
attr_reader :parameters
|
|
73
|
+
|
|
74
|
+
# @return [Hash] Raw HTTP headers
|
|
75
|
+
attr_reader :headers
|
|
76
|
+
|
|
77
|
+
# @return [String, nil] Filesystem adapter path (nil = no memory)
|
|
78
|
+
attr_reader :memory_directory
|
|
79
|
+
|
|
80
|
+
# @return [Memory::Adapters::Base, nil] Custom adapter instance
|
|
81
|
+
attr_reader :memory_adapter
|
|
82
|
+
|
|
83
|
+
# @return [Integer] Recent turns to keep in short-term memory
|
|
84
|
+
attr_reader :memory_stm_turns
|
|
85
|
+
|
|
86
|
+
# @return [Integer] Cards to retrieve per turn
|
|
87
|
+
attr_reader :memory_retrieval_top_k
|
|
88
|
+
|
|
89
|
+
# @return [Float] Hybrid search semantic weight (0.0-1.0)
|
|
90
|
+
attr_reader :memory_semantic_weight
|
|
91
|
+
|
|
92
|
+
# @return [Float] Hybrid search keyword weight (0.0-1.0)
|
|
93
|
+
attr_reader :memory_keyword_weight
|
|
94
|
+
|
|
95
|
+
# @return [Boolean] Whether to surface exploration cards as tangential memories
|
|
96
|
+
# the agent is encouraged to naturally bring up in conversation
|
|
97
|
+
attr_reader :memory_associative
|
|
98
|
+
|
|
99
|
+
# @return [Array<String>] Skill directory paths (expanded, frozen)
|
|
100
|
+
attr_reader :skills
|
|
101
|
+
|
|
102
|
+
# @return [Array<V3::MCP::ServerDefinition>] MCP server configurations (frozen)
|
|
103
|
+
attr_reader :mcp_servers
|
|
104
|
+
|
|
105
|
+
# @return [Hash, Object, nil] JSON Schema for structured output (pass-through to RubyLLM)
|
|
106
|
+
attr_reader :output_schema
|
|
107
|
+
|
|
108
|
+
# @return [String, nil] API version for OpenAI provider ("v1/responses" or "v1/chat/completions").
|
|
109
|
+
# Defaults to "v1/responses" when provider is "openai". nil for non-OpenAI providers.
|
|
110
|
+
attr_reader :api_version
|
|
111
|
+
|
|
112
|
+
# @return [Array<Hash>] Hook configurations (frozen). Each hash has :event, :block,
|
|
113
|
+
# and optional :match keys. Opaque to the definition — {Hooks::Runner} interprets them.
|
|
114
|
+
attr_reader :hooks
|
|
115
|
+
|
|
116
|
+
# @return [Symbol] Steering queue delivery mode (:all or :one_at_a_time)
|
|
117
|
+
attr_reader :steering_mode
|
|
118
|
+
|
|
119
|
+
# --- Subtask model configuration (per-agent override) ---
|
|
120
|
+
|
|
121
|
+
# @return [String, nil] Model for this agent's subtasks (nil = use global config or inherit)
|
|
122
|
+
attr_reader :subtask_model
|
|
123
|
+
|
|
124
|
+
# @return [String, nil] Provider for subtask model
|
|
125
|
+
attr_reader :subtask_provider
|
|
126
|
+
|
|
127
|
+
# @return [String, nil] Custom API base URL for subtask model
|
|
128
|
+
attr_reader :subtask_base_url
|
|
129
|
+
|
|
130
|
+
# @return [Hash] Custom HTTP headers for subtask model
|
|
131
|
+
attr_reader :subtask_headers
|
|
132
|
+
|
|
133
|
+
# @return [Hash] Raw API body parameters for subtask model
|
|
134
|
+
attr_reader :subtask_parameters
|
|
135
|
+
|
|
136
|
+
# Create a new agent definition
|
|
137
|
+
#
|
|
138
|
+
# @param name [Symbol, String] Agent identifier (required)
|
|
139
|
+
# @param description [String] Agent role description (required)
|
|
140
|
+
# @param model [String, nil] LLM model ID
|
|
141
|
+
# @param provider [String, nil] LLM provider
|
|
142
|
+
# @param system_prompt [String, nil] System prompt instructions
|
|
143
|
+
# @param tools [Array<Symbol>] Tool names
|
|
144
|
+
# @param directory [String] Working directory
|
|
145
|
+
# @param base_url [String, nil] Custom API endpoint
|
|
146
|
+
# @param max_concurrent_tools [Integer, nil] Max concurrent tool executions
|
|
147
|
+
# @param parameters [Hash] Raw API body parameters
|
|
148
|
+
# @param headers [Hash] Raw HTTP headers
|
|
149
|
+
# @param memory_directory [String, nil] Filesystem adapter path
|
|
150
|
+
# @param memory_adapter [Memory::Adapters::Base, nil] Custom adapter instance
|
|
151
|
+
# @param memory_stm_turns [Integer] Recent turns in STM
|
|
152
|
+
# @param memory_retrieval_top_k [Integer] Cards to retrieve per turn
|
|
153
|
+
# @param memory_semantic_weight [Float] Semantic search weight
|
|
154
|
+
# @param memory_keyword_weight [Float] Keyword search weight
|
|
155
|
+
# @param memory_associative [Boolean, nil] Enable associative memory
|
|
156
|
+
# @param skills [Array<String>] Skill directory paths
|
|
157
|
+
# @param mcp_servers [Array<Hash, V3::MCP::ServerDefinition>] MCP server configurations
|
|
158
|
+
# @param output_schema [Hash, Object, nil] JSON Schema for structured output (pass-through to RubyLLM)
|
|
159
|
+
# @param api_version [String, nil] API version for OpenAI provider.
|
|
160
|
+
# Valid values: "v1/responses", "v1/chat/completions".
|
|
161
|
+
# Defaults to "v1/responses" when provider is "openai". Ignored for other providers.
|
|
162
|
+
# @param hooks [Array<Hash>] Hook configurations. Each hash has :event (Symbol),
|
|
163
|
+
# :block (Proc), and optional :match keys. See {Hooks::Runner} for details.
|
|
164
|
+
# @param steering_mode [Symbol] Steering queue delivery mode (:all or :one_at_a_time).
|
|
165
|
+
# Default: :all (all steering messages injected together).
|
|
166
|
+
# @param subtask_model [String, nil] Model for this agent's subtasks
|
|
167
|
+
# @param subtask_provider [String, nil] Provider for subtask model
|
|
168
|
+
# @param subtask_base_url [String, nil] Custom API base URL for subtask model
|
|
169
|
+
# @param subtask_headers [Hash] Custom HTTP headers for subtask model
|
|
170
|
+
# @param subtask_parameters [Hash] Raw API body parameters for subtask model
|
|
171
|
+
#
|
|
172
|
+
# @raise [ConfigurationError] If required fields are missing or invalid
|
|
173
|
+
def initialize(
|
|
174
|
+
name:,
|
|
175
|
+
description:,
|
|
176
|
+
model: nil,
|
|
177
|
+
provider: nil,
|
|
178
|
+
system_prompt: nil,
|
|
179
|
+
tools: [],
|
|
180
|
+
directory: ".",
|
|
181
|
+
base_url: nil,
|
|
182
|
+
max_concurrent_tools: nil,
|
|
183
|
+
parameters: {},
|
|
184
|
+
headers: {},
|
|
185
|
+
memory_directory: nil,
|
|
186
|
+
memory_adapter: nil,
|
|
187
|
+
memory_stm_turns: nil,
|
|
188
|
+
memory_retrieval_top_k: nil,
|
|
189
|
+
memory_semantic_weight: nil,
|
|
190
|
+
memory_keyword_weight: nil,
|
|
191
|
+
memory_associative: nil,
|
|
192
|
+
skills: [],
|
|
193
|
+
mcp_servers: [],
|
|
194
|
+
output_schema: nil,
|
|
195
|
+
api_version: nil,
|
|
196
|
+
hooks: [],
|
|
197
|
+
steering_mode: :all,
|
|
198
|
+
subtask_model: nil,
|
|
199
|
+
subtask_provider: nil,
|
|
200
|
+
subtask_base_url: nil,
|
|
201
|
+
subtask_headers: {},
|
|
202
|
+
subtask_parameters: {}
|
|
203
|
+
)
|
|
204
|
+
config = Configuration.instance
|
|
205
|
+
|
|
206
|
+
@name = name.to_sym
|
|
207
|
+
@description = description
|
|
208
|
+
@model = model || config.default_model
|
|
209
|
+
@provider = provider
|
|
210
|
+
@system_prompt = system_prompt
|
|
211
|
+
@tools = Array(tools).map(&:to_sym)
|
|
212
|
+
@directory = File.expand_path(directory)
|
|
213
|
+
@base_url = base_url
|
|
214
|
+
@max_concurrent_tools = max_concurrent_tools || config.default_max_concurrent_tools
|
|
215
|
+
@parameters = parameters.freeze
|
|
216
|
+
@headers = headers.freeze
|
|
217
|
+
@memory_directory = memory_directory
|
|
218
|
+
@memory_adapter = memory_adapter
|
|
219
|
+
@memory_stm_turns = memory_stm_turns || config.default_stm_turns
|
|
220
|
+
@memory_retrieval_top_k = memory_retrieval_top_k || config.default_retrieval_top_k
|
|
221
|
+
@memory_semantic_weight = memory_semantic_weight || config.default_semantic_weight
|
|
222
|
+
@memory_keyword_weight = memory_keyword_weight || config.default_keyword_weight
|
|
223
|
+
@memory_associative = memory_associative.nil? ? config.default_associative_memory : memory_associative
|
|
224
|
+
@skills = Array(skills).map { |s| File.expand_path(s) }.freeze
|
|
225
|
+
@mcp_servers = Array(mcp_servers).map do |config|
|
|
226
|
+
config.is_a?(V3::MCP::ServerDefinition) ? config : V3::MCP::ServerDefinition.new(**config)
|
|
227
|
+
end.freeze
|
|
228
|
+
@output_schema = output_schema
|
|
229
|
+
@api_version = resolve_api_version(api_version)
|
|
230
|
+
@hooks = Array(hooks).freeze
|
|
231
|
+
@steering_mode = steering_mode.to_sym
|
|
232
|
+
@subtask_model = subtask_model
|
|
233
|
+
@subtask_provider = subtask_provider
|
|
234
|
+
@subtask_base_url = subtask_base_url
|
|
235
|
+
@subtask_headers = subtask_headers.freeze
|
|
236
|
+
@subtask_parameters = subtask_parameters.freeze
|
|
237
|
+
|
|
238
|
+
validate!
|
|
239
|
+
freeze
|
|
240
|
+
end
|
|
241
|
+
|
|
242
|
+
# Whether this agent has memory enabled
|
|
243
|
+
#
|
|
244
|
+
# @return [Boolean] true if memory_directory or memory_adapter is set
|
|
245
|
+
def memory_enabled?
|
|
246
|
+
!@memory_directory.nil? || !@memory_adapter.nil?
|
|
247
|
+
end
|
|
248
|
+
|
|
249
|
+
# Whether this agent has subtask model configuration
|
|
250
|
+
#
|
|
251
|
+
# @return [Boolean] true if any subtask_* option is set
|
|
252
|
+
def subtask_config?
|
|
253
|
+
!@subtask_model.nil? ||
|
|
254
|
+
!@subtask_provider.nil? ||
|
|
255
|
+
!@subtask_base_url.nil? ||
|
|
256
|
+
!@subtask_headers.empty? ||
|
|
257
|
+
!@subtask_parameters.empty?
|
|
258
|
+
end
|
|
259
|
+
|
|
260
|
+
private
|
|
261
|
+
|
|
262
|
+
# Resolve the effective API version based on provider
|
|
263
|
+
#
|
|
264
|
+
# When provider is "openai" and no api_version is specified,
|
|
265
|
+
# defaults to "v1/responses" (OpenAI Responses API).
|
|
266
|
+
#
|
|
267
|
+
# @param explicit_version [String, nil] Explicitly set api_version
|
|
268
|
+
# @return [String, nil] Resolved API version
|
|
269
|
+
def resolve_api_version(explicit_version)
|
|
270
|
+
openai = @provider.to_s.downcase == "openai"
|
|
271
|
+
|
|
272
|
+
if explicit_version
|
|
273
|
+
return explicit_version if openai
|
|
274
|
+
|
|
275
|
+
raise ConfigurationError,
|
|
276
|
+
"api_version is only supported for the OpenAI provider (got provider: #{@provider.inspect})"
|
|
277
|
+
end
|
|
278
|
+
|
|
279
|
+
openai ? "v1/responses" : nil
|
|
280
|
+
end
|
|
281
|
+
|
|
282
|
+
# Validate the definition
|
|
283
|
+
#
|
|
284
|
+
# @raise [ConfigurationError] If validation fails
|
|
285
|
+
def validate!
|
|
286
|
+
raise ConfigurationError, "Agent name is required" if @name.nil? || @name.to_s.strip.empty?
|
|
287
|
+
raise ConfigurationError, "Agent description is required" if @description.nil? || @description.to_s.strip.empty?
|
|
288
|
+
raise ConfigurationError, "Agent model is required" if @model.nil? || @model.to_s.strip.empty?
|
|
289
|
+
|
|
290
|
+
if @api_version && !VALID_API_VERSIONS.include?(@api_version)
|
|
291
|
+
raise ConfigurationError,
|
|
292
|
+
"Invalid api_version #{@api_version.inspect}. " \
|
|
293
|
+
"Valid values: #{VALID_API_VERSIONS.map(&:inspect).join(", ")}"
|
|
294
|
+
end
|
|
295
|
+
|
|
296
|
+
if @memory_semantic_weight < 0.0 || @memory_semantic_weight > 1.0
|
|
297
|
+
raise ConfigurationError, "memory_semantic_weight must be between 0.0 and 1.0"
|
|
298
|
+
end
|
|
299
|
+
|
|
300
|
+
if @memory_keyword_weight < 0.0 || @memory_keyword_weight > 1.0
|
|
301
|
+
raise ConfigurationError, "memory_keyword_weight must be between 0.0 and 1.0"
|
|
302
|
+
end
|
|
303
|
+
|
|
304
|
+
if @memory_stm_turns < 1
|
|
305
|
+
raise ConfigurationError, "memory_stm_turns must be at least 1"
|
|
306
|
+
end
|
|
307
|
+
|
|
308
|
+
if @memory_retrieval_top_k < 1
|
|
309
|
+
raise ConfigurationError, "memory_retrieval_top_k must be at least 1"
|
|
310
|
+
end
|
|
311
|
+
|
|
312
|
+
if @skills.any? && !@tools.include?(:Read)
|
|
313
|
+
raise ConfigurationError, "Agent with skills requires the Read tool to activate skills"
|
|
314
|
+
end
|
|
315
|
+
|
|
316
|
+
unless VALID_QUEUE_MODES.include?(@steering_mode)
|
|
317
|
+
raise ConfigurationError,
|
|
318
|
+
"Invalid steering_mode #{@steering_mode.inspect}. " \
|
|
319
|
+
"Valid values: #{VALID_QUEUE_MODES.map(&:inspect).join(", ")}"
|
|
320
|
+
end
|
|
321
|
+
|
|
322
|
+
if subtask_config? && !@tools.include?(:SubTask)
|
|
323
|
+
raise ConfigurationError,
|
|
324
|
+
"Agent '#{@name}' has subtask model configuration but does not include the :SubTask tool. " \
|
|
325
|
+
"Either add :SubTask to tools or remove subtask_* options."
|
|
326
|
+
end
|
|
327
|
+
end
|
|
328
|
+
end
|
|
329
|
+
end
|
|
330
|
+
end
|