Module: ActiveAgent::ModelCapabilities

Defined in:
lib/active_agent/model_capabilities.rb

Overview

Per-model capability quirks, applied before a request reaches the provider. Vendors ship models that reject otherwise-standard sampling parameters (thinking-first models steered by prompting/effort instead) with an API 400 — this registry strips those parameters up front so an agent configured with a shared temperature keeps working across model switches.

The built-in rules cover the known families; apps can extend the registry for new or self-hosted models:

Examples:

Register a custom rule

ActiveAgent::ModelCapabilities.register(/\Amy-reasoning-model/, unsupported: [:temperature, :top_p])

Disable sanitization entirely

ActiveAgent::ModelCapabilities.enabled = false

Constant Summary collapse

SAMPLING_PARAMS =
[ :temperature, :top_p ].freeze
BUILTIN_RULES =

Model families that reject sampling parameters with a 400:

  • Anthropic thinking-first models (Opus 4.7+, Opus 5, Sonnet 5, Fable 5 / Mythos 5)
  • OpenAI reasoning models (o-series, GPT-5 family)
[
  { pattern: /\Aclaude-(opus-5|opus-4-[78]|sonnet-5|fable-5|mythos-5)/, unsupported: SAMPLING_PARAMS },
  { pattern: /\A(o1|o3|o4)(-|$)/, unsupported: SAMPLING_PARAMS },
  { pattern: /\Agpt-5/, unsupported: SAMPLING_PARAMS }
].freeze

Class Attribute Summary collapse

Class Method Summary collapse

Class Attribute Details

.enabledObject



37
38
39
40
41
# File 'lib/active_agent/model_capabilities.rb', line 37

def enabled
  return @enabled unless @enabled.nil?

  true
end

Class Method Details

.custom_rulesObject



51
52
53
# File 'lib/active_agent/model_capabilities.rb', line 51

def custom_rules
  @custom_rules ||= []
end

.register(pattern, unsupported:) ⇒ Object

Registers an app-defined capability rule ahead of the built-ins.

Parameters:

  • pattern (Regexp)

    matched against the model name

  • unsupported (Array<Symbol>)

    parameter keys the model rejects



47
48
49
# File 'lib/active_agent/model_capabilities.rb', line 47

def register(pattern, unsupported:)
  custom_rules << { pattern: pattern, unsupported: unsupported.map(&:to_sym) }
end

.reset!Object



55
56
57
58
# File 'lib/active_agent/model_capabilities.rb', line 55

def reset!
  @custom_rules = []
  @enabled = nil
end

.sampling_supported?(model) ⇒ Boolean

Returns:

  • (Boolean)


70
71
72
# File 'lib/active_agent/model_capabilities.rb', line 70

def sampling_supported?(model)
  (unsupported_params(model) & SAMPLING_PARAMS).empty?
end

.sanitize!(parameters) ⇒ Array<Symbol>

Strips parameters the model rejects, in place. Returns the removed keys (empty when nothing applied).

Parameters:

  • parameters (Hash)

    prepared prompt parameters (must carry :model)

Returns:

  • (Array<Symbol>)

    removed parameter keys



79
80
81
82
83
84
85
86
# File 'lib/active_agent/model_capabilities.rb', line 79

def sanitize!(parameters)
  return [] unless enabled
  return [] unless parameters.is_a?(Hash)

  removed = unsupported_params(parameters[:model]).select { |key| parameters.key?(key) }
  removed.each { |key| parameters.delete(key) }
  removed
end

.unsupported_params(model) ⇒ Array<Symbol>

Returns parameter keys the model rejects.

Returns:

  • (Array<Symbol>)

    parameter keys the model rejects



61
62
63
64
65
66
67
68
# File 'lib/active_agent/model_capabilities.rb', line 61

def unsupported_params(model)
  return [] if model.nil?

  (custom_rules + BUILTIN_RULES).each do |rule|
    return rule[:unsupported] if model.to_s.match?(rule[:pattern])
  end
  []
end