Class: SwarmSDK::Agent::Chat
- Inherits:
-
Object
- Object
- SwarmSDK::Agent::Chat
- Includes:
- SwarmSDK::Agent::ChatHelpers::EventEmitter, SwarmSDK::Agent::ChatHelpers::HookIntegration, SwarmSDK::Agent::ChatHelpers::Instrumentation, SwarmSDK::Agent::ChatHelpers::LlmConfiguration, SwarmSDK::Agent::ChatHelpers::LoggingHelpers, SwarmSDK::Agent::ChatHelpers::Serialization, SwarmSDK::Agent::ChatHelpers::SystemReminders, SwarmSDK::Agent::ChatHelpers::TokenTracking
- Defined in:
- lib/swarm_sdk/agent/chat.rb
Overview
Chat wraps RubyLLM::Chat to provide SwarmSDK orchestration capabilities
Architecture
This class uses composition with RubyLLM::Chat:
- RubyLLM::Chat handles: LLM API, messages, tools, concurrent execution
- SwarmSDK::Agent::Chat adds: hooks, reminders, semaphores, event enrichment
ChatHelpers Module Architecture
Chat is decomposed into 8 focused helper modules to manage complexity:
Core Functionality
- EventEmitter: Multi-subscriber event callbacks for tool/lifecycle events.
Provides
subscribe,emit_event,clear_subscribersfor observable behavior. - LoggingHelpers: Formatting tool call information for structured JSON logs. Converts tool calls/results to loggable hashes with sanitization.
- LlmConfiguration: Model selection, provider setup, and API configuration. Resolves provider from model, handles model aliases, builds connection config.
- SystemReminders: Dynamic system message injection based on agent state. Collects reminders from plugins, context trackers, and other sources.
Cross-Cutting Concerns
- Instrumentation: LLM API request/response logging via Faraday middleware. Wraps HTTP calls to capture timing, tokens, and error information.
- HookIntegration: Pre/post tool execution callbacks and delegation hooks. Integrates with SwarmSDK Hooks::Registry for lifecycle events.
- TokenTracking: Usage statistics and cost calculation per conversation. Accumulates input/output tokens across all LLM calls.
State Management
- Serialization: Snapshot/restore for session persistence. Saves/restores message history, tool states, and agent context.
Module Dependencies
EventEmitter <-- HookIntegration (event emission for hooks)
TokenTracking <-- Instrumentation (usage data collection)
SystemReminders <-- uses ContextTracker instance (not a module)
LoggingHelpers <-- EventEmitter (log event formatting)
Design Rationale
This decomposition follows Single Responsibility Principle. Each module handles one concern. They access shared Chat internals (@llm_chat, @messages, etc.) which makes them tightly coupled to Chat, but this keeps the main Chat class focused on orchestration rather than implementation details. The modules are intentionally NOT standalone - they augment Chat with specific capabilities.
Rate Limiting Strategy
Two-level semaphore system prevents API quota exhaustion in hierarchical agent trees:
- Global semaphore - Serializes ask() calls across entire swarm
- Local semaphore - Limits concurrent tool calls per agent (via RubyLLM)
Event Flow
RubyLLM events → SwarmSDK subscribes → enriches with context → emits SwarmSDK events This allows hooks to fire on SwarmSDK events with full agent context.
Defined Under Namespace
Classes: SymbolKeyHash
Instance Attribute Summary collapse
-
#active_skill_path ⇒ String?
Get active skill path (for backward compatibility).
-
#agent_context ⇒ Object
readonly
SwarmSDK-specific accessors.
-
#context_manager ⇒ Object
readonly
SwarmSDK-specific accessors.
-
#context_tracker ⇒ Object
readonly
SwarmSDK-specific accessors.
-
#global_semaphore ⇒ Object
readonly
SwarmSDK-specific accessors.
-
#last_todowrite_message_index ⇒ Object
SwarmSDK-specific accessors.
-
#provider ⇒ Object
readonly
SwarmSDK-specific accessors.
-
#real_model_info ⇒ Object
readonly
SwarmSDK-specific accessors.
-
#skill_state ⇒ Object
readonly
SwarmSDK-specific accessors.
-
#tool_registry ⇒ Object
readonly
SwarmSDK-specific accessors.
Attributes included from SwarmSDK::Agent::ChatHelpers::HookIntegration
#hook_agent_hooks, #hook_executor, #hook_swarm
Instance Method Summary collapse
-
#activate_tools_for_prompt ⇒ void
Activate tools for the current prompt (Plan 025: Lazy Tool Activation).
-
#add_ephemeral_reminder(reminder) ⇒ void
Add an ephemeral reminder to the most recent message.
-
#add_message(message_or_attributes) ⇒ RubyLLM::Message
Add a message to the conversation history.
-
#add_tool(tool) ⇒ self
Add a tool to this chat.
-
#ask(prompt, clear_context: false, **options) ⇒ RubyLLM::Message
Send a message to the LLM and get a response.
-
#assistant_messages ⇒ Array<RubyLLM::Message>
Get all assistant messages.
-
#clear_conversation ⇒ void
Clear conversation history.
-
#clear_skill ⇒ void
Clear loaded skill (return to all tools).
-
#complete(**_options, &block) ⇒ RubyLLM::Message
Complete the current conversation (no additional prompt).
-
#configure_system_prompt(prompt, replace: false) ⇒ self
Configure system prompt for the conversation.
-
#emit_model_lookup_warning(agent_name) ⇒ Object
Emit model lookup warning if one occurred during initialization.
-
#find_last_message {|msg| ... } ⇒ RubyLLM::Message?
Find the last message matching a condition.
-
#find_last_message_index {|msg| ... } ⇒ Integer?
Find the index of last message matching a condition.
-
#has_tool?(name) ⇒ Boolean
Tool introspection.
- #has_user_message? ⇒ Boolean
-
#initialize(definition:, agent_name: nil, global_semaphore: nil, **options) ⇒ Chat
constructor
Initialize AgentChat with RubyLLM::Chat wrapper.
- #last_assistant_message ⇒ Object
-
#load_skill_state(state) ⇒ void
Load skill state (called by LoadSkill tool).
-
#message_count ⇒ Object
Message introspection.
-
#messages ⇒ Array<RubyLLM::Message>
Read-only access to conversation messages.
- #model_context_window ⇒ Object
-
#model_id ⇒ Object
Model information.
- #model_provider ⇒ Object
-
#non_delegation_tool_names ⇒ Array<String>
Get tool names that are NOT delegation tools.
- #remove_tool(name) ⇒ Object
-
#replace_messages(new_messages) ⇒ self
Atomically replace all conversation messages.
-
#setup_context(context) ⇒ Object
Setup agent context.
-
#setup_logging ⇒ void
Setup logging callbacks.
-
#setup_tool_activation(tool_configurator:, agent_definition:) ⇒ void
Setup tool activation dependencies (Plan 025).
-
#skill_loaded? ⇒ Boolean
Check if a skill is currently loaded.
-
#streaming_enabled? ⇒ Boolean
Check if streaming is enabled for this agent.
- #tool_count ⇒ Object
- #tool_names ⇒ Object
-
#tools ⇒ Hash
Direct access to tools hash for advanced operations.
Methods included from SwarmSDK::Agent::ChatHelpers::Serialization
#conversation_snapshot, #restore_conversation
Methods included from SwarmSDK::Agent::ChatHelpers::TokenTracking
#compact_context, #context_limit, #context_usage_percentage, #cumulative_cache_creation_tokens, #cumulative_cached_tokens, #cumulative_input_cost, #cumulative_input_tokens, #cumulative_output_cost, #cumulative_output_tokens, #cumulative_total_cost, #cumulative_total_tokens, #effective_input_tokens, #tokens_remaining
Methods included from SwarmSDK::Agent::ChatHelpers::SystemReminders
#collect_plugin_reminders, #collect_system_reminders
Methods included from SwarmSDK::Agent::ChatHelpers::HookIntegration
#add_hook, #check_context_warnings, #setup_hooks, #trigger_post_tool_use, #trigger_pre_tool_use
Methods included from SwarmSDK::Agent::ChatHelpers::LoggingHelpers
#calculate_cost, #format_tool_calls, #serialize_result, #zero_cost
Methods included from SwarmSDK::Agent::ChatHelpers::EventEmitter
#callback_count, #clear_callbacks, #initialize_event_emitter, #on_end_message, #on_new_message, #on_tool_call, #on_tool_result, #once, #subscribe
Constructor Details
#initialize(definition:, agent_name: nil, global_semaphore: nil, **options) ⇒ Chat
Initialize AgentChat with RubyLLM::Chat wrapper
115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 |
# File 'lib/swarm_sdk/agent/chat.rb', line 115 def initialize(definition:, agent_name: nil, global_semaphore: nil, **) # Initialize event emitter system initialize_event_emitter # Extract configuration from definition model_id = definition[:model] provider_name = definition[:provider] context_window = definition[:context_window] max_concurrent_tools = definition[:max_concurrent_tools] base_url = definition[:base_url] api_version = definition[:api_version] request_timeout = definition[:request_timeout] || SwarmSDK.config.agent_request_timeout assume_model_exists = definition[:assume_model_exists] system_prompt = definition[:system_prompt] parameters = definition[:parameters] custom_headers = definition[:headers] # Agent identifier (for plugin callbacks) @agent_name = agent_name # Turn timeout (external timeout for entire ask() call) @turn_timeout = definition[:turn_timeout] # Streaming configuration @streaming_enabled = definition[:streaming] @last_chunk_type = nil # Track chunk type transitions # Context manager for ephemeral messages @context_manager = ContextManager.new # Rate limiting @global_semaphore = global_semaphore @explicit_context_window = context_window # Serialize ask() calls to prevent message corruption @ask_semaphore = Async::Semaphore.new(1) # Track TodoWrite usage for periodic reminders @last_todowrite_message_index = nil # Agent context for logging (set via setup_context) @agent_context = nil # Context tracker (created after agent_context is set) @context_tracker = nil # Tool registry for lazy tool activation (Phase 3 - Plan 025) @tool_registry = Agent::ToolRegistry.new # Track loaded skill state (Phase 2 - Plan 025) @skill_state = nil # Tool activation dependencies (set by setup_tool_activation after initialization) @tool_configurator = nil @agent_definition = nil # Create internal RubyLLM::Chat instance @llm_chat = create_llm_chat( model_id: model_id, provider_name: provider_name, base_url: base_url, api_version: api_version, timeout: request_timeout, assume_model_exists: assume_model_exists, max_concurrent_tools: max_concurrent_tools, ) # Extract provider from RubyLLM::Chat for instrumentation # Must be done after create_llm_chat since with_responses_api() may swap provider # NOTE: RubyLLM doesn't expose provider publicly, but we need it for Faraday middleware # rubocop:disable Security/NoReflectionMethods @provider = @llm_chat.instance_variable_get(:@provider) # rubocop:enable Security/NoReflectionMethods # Try to fetch real model info for accurate context tracking fetch_real_model_info(model_id) # Configure system prompt, parameters, headers, and thinking configure_system_prompt(system_prompt) if system_prompt configure_parameters(parameters) configure_headers(custom_headers) configure_thinking(definition[:thinking]) # Setup around_tool_execution hook for SwarmSDK orchestration setup_tool_execution_hook # Setup around_llm_request hook for ephemeral message injection setup_llm_request_hook # Setup event bridging from RubyLLM to SwarmSDK setup_event_bridging end |
Instance Attribute Details
#active_skill_path ⇒ String?
Get active skill path (for backward compatibility)
484 485 486 |
# File 'lib/swarm_sdk/agent/chat.rb', line 484 def active_skill_path @skill_state&.file_path end |
#agent_context ⇒ Object (readonly)
SwarmSDK-specific accessors
96 97 98 |
# File 'lib/swarm_sdk/agent/chat.rb', line 96 def agent_context @agent_context end |
#context_manager ⇒ Object (readonly)
SwarmSDK-specific accessors
96 97 98 |
# File 'lib/swarm_sdk/agent/chat.rb', line 96 def context_manager @context_manager end |
#context_tracker ⇒ Object (readonly)
SwarmSDK-specific accessors
96 97 98 |
# File 'lib/swarm_sdk/agent/chat.rb', line 96 def context_tracker @context_tracker end |
#global_semaphore ⇒ Object (readonly)
SwarmSDK-specific accessors
96 97 98 |
# File 'lib/swarm_sdk/agent/chat.rb', line 96 def global_semaphore @global_semaphore end |
#last_todowrite_message_index ⇒ Object
SwarmSDK-specific accessors
96 97 98 |
# File 'lib/swarm_sdk/agent/chat.rb', line 96 def @last_todowrite_message_index end |
#provider ⇒ Object (readonly)
SwarmSDK-specific accessors
96 97 98 |
# File 'lib/swarm_sdk/agent/chat.rb', line 96 def provider @provider end |
#real_model_info ⇒ Object (readonly)
SwarmSDK-specific accessors
96 97 98 |
# File 'lib/swarm_sdk/agent/chat.rb', line 96 def real_model_info @real_model_info end |
#skill_state ⇒ Object (readonly)
SwarmSDK-specific accessors
96 97 98 |
# File 'lib/swarm_sdk/agent/chat.rb', line 96 def skill_state @skill_state end |
#tool_registry ⇒ Object (readonly)
SwarmSDK-specific accessors
96 97 98 |
# File 'lib/swarm_sdk/agent/chat.rb', line 96 def tool_registry @tool_registry end |
Instance Method Details
#activate_tools_for_prompt ⇒ void
This method returns an undefined value.
Activate tools for the current prompt (Plan 025: Lazy Tool Activation)
Called before each LLM request to set active toolset based on skill state. Replaces @llm_chat.tools with active subset from registry.
This is public so it can be called during initialization to populate tools.
Logic:
- If no skill loaded: ALL tools from registry
- If skill restricts tools: skill's tools + non-removable tools
- Skill permissions applied during activation (wrapping base_instance)
509 510 511 512 513 514 515 516 517 518 519 520 521 |
# File 'lib/swarm_sdk/agent/chat.rb', line 509 def activate_tools_for_prompt # Get active tools based on skill state active = @tool_registry.active_tools( skill_state: @skill_state, tool_configurator: @tool_configurator, agent_definition: @agent_definition, ) # Replace RubyLLM::Chat tools with active subset # CRITICAL: RubyLLM looks up tools by SYMBOL keys, must store with symbols! @llm_chat.tools.clear active.each { |name, instance| @llm_chat.tools[name.to_sym] = instance } end |
#add_ephemeral_reminder(reminder) ⇒ void
This method returns an undefined value.
Add an ephemeral reminder to the most recent message
The reminder will be sent to the LLM but not persisted in message history. This encapsulates the internal message array access.
354 355 356 |
# File 'lib/swarm_sdk/agent/chat.rb', line 354 def add_ephemeral_reminder(reminder) @context_manager&.add_ephemeral_reminder(reminder, messages_array: @llm_chat.) end |
#add_message(message_or_attributes) ⇒ RubyLLM::Message
Add a message to the conversation history
Automatically extracts and strips system reminders, tracking them as ephemeral.
561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 |
# File 'lib/swarm_sdk/agent/chat.rb', line 561 def () = if .is_a?(RubyLLM::Message) else RubyLLM::Message.new() end # Extract system reminders if present content_str = .content.is_a?(RubyLLM::Content) ? .content.text : .content.to_s if @context_manager.has_system_reminders?(content_str) reminders = @context_manager.extract_system_reminders(content_str) clean_content_str = @context_manager.strip_system_reminders(content_str) clean_content = if .content.is_a?(RubyLLM::Content) RubyLLM::Content.new(clean_content_str, .content.) else clean_content_str end = RubyLLM::Message.new( role: .role, content: clean_content, tool_call_id: .tool_call_id, tool_calls: .tool_calls, model_id: .model_id, input_tokens: .input_tokens, output_tokens: .output_tokens, cached_tokens: .cached_tokens, cache_creation_tokens: .cache_creation_tokens, ) @llm_chat.() # Track reminders as ephemeral reminders.each do |reminder| @context_manager.add_ephemeral_reminder(reminder, messages_array: ) end else @llm_chat.() end end |
#add_tool(tool) ⇒ self
Add a tool to this chat
423 424 425 426 |
# File 'lib/swarm_sdk/agent/chat.rb', line 423 def add_tool(tool) @llm_chat.with_tool(tool) self end |
#ask(prompt, clear_context: false, **options) ⇒ RubyLLM::Message
Send a message to the LLM and get a response
This method:
- Serializes concurrent asks via @ask_semaphore
- Optionally clears conversation context (inside semaphore for safety)
- Adds CLEAN user message to history (no reminders)
- Injects system reminders as ephemeral content (sent to LLM but not stored)
- Triggers user_prompt hooks
- Acquires global semaphore for LLM call
- Delegates to RubyLLM::Chat for actual execution
542 543 544 545 546 547 548 549 550 551 552 553 |
# File 'lib/swarm_sdk/agent/chat.rb', line 542 def ask(prompt, clear_context: false, **) @ask_semaphore.acquire do # Clear inside semaphore so concurrent callers don't corrupt each other's messages clear_conversation if clear_context if @turn_timeout execute_with_turn_timeout(prompt, ) else execute_ask(prompt, ) end end end |
#assistant_messages ⇒ Array<RubyLLM::Message>
Get all assistant messages
316 317 318 |
# File 'lib/swarm_sdk/agent/chat.rb', line 316 def @llm_chat..select { |msg| msg.role == :assistant } end |
#clear_conversation ⇒ void
This method returns an undefined value.
Clear conversation history
491 492 493 494 |
# File 'lib/swarm_sdk/agent/chat.rb', line 491 def clear_conversation @llm_chat. @context_manager&.clear_ephemeral end |
#clear_skill ⇒ void
This method returns an undefined value.
Clear loaded skill (return to all tools)
470 471 472 |
# File 'lib/swarm_sdk/agent/chat.rb', line 470 def clear_skill @skill_state = nil end |
#complete(**_options, &block) ⇒ RubyLLM::Message
Complete the current conversation (no additional prompt)
Delegates to RubyLLM::Chat#complete() which handles:
- LLM API calls (with around_llm_request hook for ephemeral injection)
- Tool execution (with around_tool_execution hook for SwarmSDK hooks)
- Automatic tool loop (continues until no more tool calls)
SwarmSDK adds:
- Semaphore rate limiting (ask + global)
- Finish marker handling (finish_agent, finish_swarm)
442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 |
# File 'lib/swarm_sdk/agent/chat.rb', line 442 def complete(**, &block) @ask_semaphore.acquire do execute_with_global_semaphore do result = catch(:finish_agent) do catch(:finish_swarm) do # Delegate to RubyLLM::Chat#complete() # Hooks handle ephemeral injection and tool orchestration @llm_chat.complete(&block) end end # Handle finish markers thrown by hooks handle_finish_marker(result) end end end |
#configure_system_prompt(prompt, replace: false) ⇒ self
Configure system prompt for the conversation
414 415 416 417 |
# File 'lib/swarm_sdk/agent/chat.rb', line 414 def configure_system_prompt(prompt, replace: false) @llm_chat.with_instructions(prompt, replace: replace) self end |
#emit_model_lookup_warning(agent_name) ⇒ Object
Emit model lookup warning if one occurred during initialization
393 394 395 396 397 398 399 400 401 402 403 404 405 |
# File 'lib/swarm_sdk/agent/chat.rb', line 393 def emit_model_lookup_warning(agent_name) return unless @model_lookup_error LogStream.emit( type: "model_lookup_warning", agent: agent_name, swarm_id: @agent_context&.swarm_id, parent_swarm_id: @agent_context&.parent_swarm_id, model: @model_lookup_error[:model], error_message: @model_lookup_error[:error_message], suggestions: @model_lookup_error[:suggestions].map { |s| { id: s.id, name: s.name, context_window: s.context_window } }, ) end |
#find_last_message {|msg| ... } ⇒ RubyLLM::Message?
Find the last message matching a condition
324 325 326 |
# File 'lib/swarm_sdk/agent/chat.rb', line 324 def (&block) @llm_chat..reverse.find(&block) end |
#find_last_message_index {|msg| ... } ⇒ Integer?
Find the index of last message matching a condition
332 333 334 |
# File 'lib/swarm_sdk/agent/chat.rb', line 332 def (&block) @llm_chat..rindex(&block) end |
#has_tool?(name) ⇒ Boolean
Tool introspection
232 233 234 |
# File 'lib/swarm_sdk/agent/chat.rb', line 232 def has_tool?(name) @llm_chat.tools.key?(name.to_s) || @llm_chat.tools.key?(name.to_sym) end |
#has_user_message? ⇒ Boolean
282 283 284 |
# File 'lib/swarm_sdk/agent/chat.rb', line 282 def @llm_chat..any? { |msg| msg.role == :user } end |
#last_assistant_message ⇒ Object
286 287 288 |
# File 'lib/swarm_sdk/agent/chat.rb', line 286 def @llm_chat..reverse.find { |msg| msg.role == :assistant } end |
#load_skill_state(state) ⇒ void
This method returns an undefined value.
Load skill state (called by LoadSkill tool)
463 464 465 |
# File 'lib/swarm_sdk/agent/chat.rb', line 463 def load_skill_state(state) @skill_state = state end |
#message_count ⇒ Object
Message introspection
278 279 280 |
# File 'lib/swarm_sdk/agent/chat.rb', line 278 def @llm_chat..size end |
#messages ⇒ Array<RubyLLM::Message>
Read-only access to conversation messages
Returns a copy of the message array for safe enumeration. External code should use this instead of internal_messages.
296 297 298 |
# File 'lib/swarm_sdk/agent/chat.rb', line 296 def @llm_chat..dup end |
#model_context_window ⇒ Object
227 228 229 |
# File 'lib/swarm_sdk/agent/chat.rb', line 227 def model_context_window @real_model_info&.context_window || @llm_chat.model.context_window end |
#model_id ⇒ Object
Model information
219 220 221 |
# File 'lib/swarm_sdk/agent/chat.rb', line 219 def model_id @llm_chat.model.id end |
#model_provider ⇒ Object
223 224 225 |
# File 'lib/swarm_sdk/agent/chat.rb', line 223 def model_provider @llm_chat.model.provider end |
#non_delegation_tool_names ⇒ Array<String>
Get tool names that are NOT delegation tools
339 340 341 342 343 344 345 |
# File 'lib/swarm_sdk/agent/chat.rb', line 339 def non_delegation_tool_names if @agent_context @llm_chat.tools.keys.reject { |name| @agent_context.delegation_tool?(name.to_s) } else @llm_chat.tools.keys end end |
#remove_tool(name) ⇒ Object
244 245 246 |
# File 'lib/swarm_sdk/agent/chat.rb', line 244 def remove_tool(name) @llm_chat.tools.delete(name.to_s) || @llm_chat.tools.delete(name.to_sym) end |
#replace_messages(new_messages) ⇒ self
Atomically replace all conversation messages
Used for context compaction and state restoration. This is the safe way to manipulate messages from external code.
307 308 309 310 311 |
# File 'lib/swarm_sdk/agent/chat.rb', line 307 def () @llm_chat..clear .each { |msg| @llm_chat. << msg } self end |
#setup_context(context) ⇒ Object
Setup agent context
363 364 365 366 |
# File 'lib/swarm_sdk/agent/chat.rb', line 363 def setup_context(context) @agent_context = context @context_tracker = ChatHelpers::ContextTracker.new(self, context) end |
#setup_logging ⇒ void
This method returns an undefined value.
Setup logging callbacks
371 372 373 374 375 376 |
# File 'lib/swarm_sdk/agent/chat.rb', line 371 def setup_logging raise StateError, "Agent context not set. Call setup_context first." unless @agent_context @context_tracker.setup_logging inject_llm_instrumentation end |
#setup_tool_activation(tool_configurator:, agent_definition:) ⇒ void
This method returns an undefined value.
Setup tool activation dependencies (Plan 025)
Must be called after tool registration to enable permission wrapping during activation.
385 386 387 388 |
# File 'lib/swarm_sdk/agent/chat.rb', line 385 def setup_tool_activation(tool_configurator:, agent_definition:) @tool_configurator = tool_configurator @agent_definition = agent_definition end |
#skill_loaded? ⇒ Boolean
Check if a skill is currently loaded
477 478 479 |
# File 'lib/swarm_sdk/agent/chat.rb', line 477 def skill_loaded? !@skill_state.nil? end |
#streaming_enabled? ⇒ Boolean
Check if streaming is enabled for this agent
214 215 216 |
# File 'lib/swarm_sdk/agent/chat.rb', line 214 def streaming_enabled? @streaming_enabled end |
#tool_count ⇒ Object
240 241 242 |
# File 'lib/swarm_sdk/agent/chat.rb', line 240 def tool_count @llm_chat.tools.size end |
#tool_names ⇒ Object
236 237 238 |
# File 'lib/swarm_sdk/agent/chat.rb', line 236 def tool_names @llm_chat.tools.values.map(&:name).sort end |
#tools ⇒ Hash
Direct access to tools hash for advanced operations
Use with caution - prefer has_tool?, tool_names, remove_tool for most cases. This is provided for:
- Direct tool execution in tests
- Advanced tool manipulation
Returns a hash wrapper that supports both string and symbol keys for test convenience.
258 259 260 261 |
# File 'lib/swarm_sdk/agent/chat.rb', line 258 def tools # Return a fresh wrapper each time (since @llm_chat.tools may change) SymbolKeyHash.new(@llm_chat.tools) end |