Class: AgentCliRuntime::Profile
- Inherits:
-
Object
- Object
- AgentCliRuntime::Profile
- Defined in:
- lib/agent_cli_runtime/profile.rb
Constant Summary collapse
- PROMPT_STYLES =
%i[positional headless_flag_value stdin].freeze
- WORKSPACE_WRITE_PERMISSION_MODE =
"workspace-write".freeze
- READ_ONLY_PERMISSION_MODE =
"read-only".freeze
- CAPTURE_TIMEOUT_SECONDS =
10- CAPTURE_POLL_SECONDS =
0.01- CAPTURE_TERM_GRACE_SECONDS =
0.2- CAPTURE_REAP_GRACE_SECONDS =
0.2
Instance Attribute Summary collapse
-
#add_dir_flag ⇒ Object
readonly
Returns the value of attribute add_dir_flag.
-
#bin_default ⇒ Object
readonly
Returns the value of attribute bin_default.
-
#budget_flag ⇒ Object
readonly
Returns the value of attribute budget_flag.
-
#cli_capabilities ⇒ Object
readonly
Returns the value of attribute cli_capabilities.
-
#declared_capability_support ⇒ Object
readonly
Returns the value of attribute declared_capability_support.
-
#effort_argument_builder ⇒ Object
readonly
Returns the value of attribute effort_argument_builder.
-
#env_bin_override_keys ⇒ Object
readonly
Returns the value of attribute env_bin_override_keys.
-
#headless_flag ⇒ Object
readonly
Returns the value of attribute headless_flag.
-
#launcher_identity ⇒ Object
readonly
Returns the value of attribute launcher_identity.
-
#min_version ⇒ Object
readonly
Returns the value of attribute min_version.
-
#model_argument_builder ⇒ Object
readonly
Returns the value of attribute model_argument_builder.
-
#name ⇒ Object
readonly
Returns the value of attribute name.
-
#output_format_flags ⇒ Object
readonly
Returns the value of attribute output_format_flags.
-
#permission_skip_flag ⇒ Object
readonly
Returns the value of attribute permission_skip_flag.
-
#prompt_style ⇒ Object
readonly
Returns the value of attribute prompt_style.
-
#read_only_flags ⇒ Object
readonly
Returns the value of attribute read_only_flags.
-
#tool_scope_flags ⇒ Object
readonly
Returns the value of attribute tool_scope_flags.
-
#version_flag ⇒ Object
readonly
Returns the value of attribute version_flag.
-
#workspace_write_flags ⇒ Object
readonly
Returns the value of attribute workspace_write_flags.
Instance Method Summary collapse
- #auth_configuration(home: nil, env: ENV) ⇒ Object
- #bin(env: ENV) ⇒ Object
- #binary_installed?(env: ENV) ⇒ Boolean
- #check_version!(env: ENV) ⇒ Object
- #extract_usage_event(event) ⇒ Object
- #identity_arguments(model:, effort:, pin_model: true) ⇒ Object
-
#initialize(name:, bin_default:, headless_flag:, version_flag:, env_bin_override_keys: [], permission_skip_flag: nil, workspace_write_flags: [], read_only_flags: [], add_dir_flag: nil, tool_scope_flags: {}, budget_flag: nil, output_format_flags: [], min_version: nil, prompt_style: :positional, model_argument_builder: nil, effort_argument_builder: nil, launcher_identity: nil, usage_extractor: nil, auth_configuration_probe: nil, cli_capabilities: {}, raw_cli_arguments_supported: false) ⇒ Profile
constructor
A new instance of Profile.
- #permission_flags(permission_mode = nil) ⇒ Object
- #raw_cli_arguments_supported? ⇒ Boolean
- #require_cli_capability!(capability) ⇒ Object
Constructor Details
#initialize(name:, bin_default:, headless_flag:, version_flag:, env_bin_override_keys: [], permission_skip_flag: nil, workspace_write_flags: [], read_only_flags: [], add_dir_flag: nil, tool_scope_flags: {}, budget_flag: nil, output_format_flags: [], min_version: nil, prompt_style: :positional, model_argument_builder: nil, effort_argument_builder: nil, launcher_identity: nil, usage_extractor: nil, auth_configuration_probe: nil, cli_capabilities: {}, raw_cli_arguments_supported: false) ⇒ Profile
Returns a new instance of Profile.
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 61 62 63 64 65 66 67 68 69 70 |
# File 'lib/agent_cli_runtime/profile.rb', line 30 def initialize(name:, bin_default:, headless_flag:, version_flag:, env_bin_override_keys: [], permission_skip_flag: nil, workspace_write_flags: [], read_only_flags: [], add_dir_flag: nil, tool_scope_flags: {}, budget_flag: nil, output_format_flags: [], min_version: nil, prompt_style: :positional, model_argument_builder: nil, effort_argument_builder: nil, launcher_identity: nil, usage_extractor: nil, auth_configuration_probe: nil, cli_capabilities: {}, raw_cli_arguments_supported: false) normalized_prompt_style = prompt_style.to_sym unless PROMPT_STYLES.include?(normalized_prompt_style) raise ArgumentError, "unknown prompt_style #{prompt_style.inspect}; valid: #{PROMPT_STYLES.inspect}" end @name = name.to_sym @bin_default = immutable_string(bin_default) @env_bin_override_keys = immutable_strings(env_bin_override_keys) @headless_flag = immutable_string(headless_flag) @permission_skip_flag = .nil? ? nil : immutable_string() @workspace_write_flags = immutable_strings(workspace_write_flags) @read_only_flags = immutable_strings(read_only_flags) @add_dir_flag = add_dir_flag.nil? ? nil : immutable_string(add_dir_flag) @tool_scope_flags = normalize_tool_scope_flags(tool_scope_flags) @budget_flag = budget_flag.nil? ? nil : immutable_string(budget_flag) @output_format_flags = immutable_strings(output_format_flags) @version_flag = immutable_string(version_flag) @min_version = min_version.nil? ? nil : immutable_string(min_version) @prompt_style = normalized_prompt_style @model_argument_builder = model_argument_builder @effort_argument_builder = effort_argument_builder @launcher_identity = immutable_string(launcher_identity || "agent-cli-runtime/v1:#{@name}") @usage_extractor = usage_extractor || ->(_event) { nil } @auth_configuration_probe = auth_configuration_probe @cli_capabilities = normalize_cli_capabilities(cli_capabilities) @raw_cli_arguments_supported = raw_cli_arguments_supported == true @declared_capability_support = build_declared_capability_support freeze end |
Instance Attribute Details
#add_dir_flag ⇒ Object (readonly)
Returns the value of attribute add_dir_flag.
22 23 24 |
# File 'lib/agent_cli_runtime/profile.rb', line 22 def add_dir_flag @add_dir_flag end |
#bin_default ⇒ Object (readonly)
Returns the value of attribute bin_default.
22 23 24 |
# File 'lib/agent_cli_runtime/profile.rb', line 22 def bin_default @bin_default end |
#budget_flag ⇒ Object (readonly)
Returns the value of attribute budget_flag.
22 23 24 |
# File 'lib/agent_cli_runtime/profile.rb', line 22 def budget_flag @budget_flag end |
#cli_capabilities ⇒ Object (readonly)
Returns the value of attribute cli_capabilities.
22 23 24 |
# File 'lib/agent_cli_runtime/profile.rb', line 22 def cli_capabilities @cli_capabilities end |
#declared_capability_support ⇒ Object (readonly)
Returns the value of attribute declared_capability_support.
22 23 24 |
# File 'lib/agent_cli_runtime/profile.rb', line 22 def declared_capability_support @declared_capability_support end |
#effort_argument_builder ⇒ Object (readonly)
Returns the value of attribute effort_argument_builder.
22 23 24 |
# File 'lib/agent_cli_runtime/profile.rb', line 22 def effort_argument_builder @effort_argument_builder end |
#env_bin_override_keys ⇒ Object (readonly)
Returns the value of attribute env_bin_override_keys.
22 23 24 |
# File 'lib/agent_cli_runtime/profile.rb', line 22 def env_bin_override_keys @env_bin_override_keys end |
#headless_flag ⇒ Object (readonly)
Returns the value of attribute headless_flag.
22 23 24 |
# File 'lib/agent_cli_runtime/profile.rb', line 22 def headless_flag @headless_flag end |
#launcher_identity ⇒ Object (readonly)
Returns the value of attribute launcher_identity.
22 23 24 |
# File 'lib/agent_cli_runtime/profile.rb', line 22 def launcher_identity @launcher_identity end |
#min_version ⇒ Object (readonly)
Returns the value of attribute min_version.
22 23 24 |
# File 'lib/agent_cli_runtime/profile.rb', line 22 def min_version @min_version end |
#model_argument_builder ⇒ Object (readonly)
Returns the value of attribute model_argument_builder.
22 23 24 |
# File 'lib/agent_cli_runtime/profile.rb', line 22 def model_argument_builder @model_argument_builder end |
#name ⇒ Object (readonly)
Returns the value of attribute name.
22 23 24 |
# File 'lib/agent_cli_runtime/profile.rb', line 22 def name @name end |
#output_format_flags ⇒ Object (readonly)
Returns the value of attribute output_format_flags.
22 23 24 |
# File 'lib/agent_cli_runtime/profile.rb', line 22 def output_format_flags @output_format_flags end |
#permission_skip_flag ⇒ Object (readonly)
Returns the value of attribute permission_skip_flag.
22 23 24 |
# File 'lib/agent_cli_runtime/profile.rb', line 22 def @permission_skip_flag end |
#prompt_style ⇒ Object (readonly)
Returns the value of attribute prompt_style.
22 23 24 |
# File 'lib/agent_cli_runtime/profile.rb', line 22 def prompt_style @prompt_style end |
#read_only_flags ⇒ Object (readonly)
Returns the value of attribute read_only_flags.
22 23 24 |
# File 'lib/agent_cli_runtime/profile.rb', line 22 def read_only_flags @read_only_flags end |
#tool_scope_flags ⇒ Object (readonly)
Returns the value of attribute tool_scope_flags.
22 23 24 |
# File 'lib/agent_cli_runtime/profile.rb', line 22 def tool_scope_flags @tool_scope_flags end |
#version_flag ⇒ Object (readonly)
Returns the value of attribute version_flag.
22 23 24 |
# File 'lib/agent_cli_runtime/profile.rb', line 22 def version_flag @version_flag end |
#workspace_write_flags ⇒ Object (readonly)
Returns the value of attribute workspace_write_flags.
22 23 24 |
# File 'lib/agent_cli_runtime/profile.rb', line 22 def workspace_write_flags @workspace_write_flags end |
Instance Method Details
#auth_configuration(home: nil, env: ENV) ⇒ Object
182 183 184 185 186 187 188 189 190 191 192 193 194 195 |
# File 'lib/agent_cli_runtime/profile.rb', line 182 def auth_configuration(home: nil, env: ENV) return AuthConfiguration.new(status: :not_checked) unless @auth_configuration_probe result = @auth_configuration_probe.call(home: home, env: env) return result if result.is_a?(AuthConfiguration) raise TypeError, "auth_configuration_probe must return AgentCliRuntime::AuthConfiguration" rescue StandardError => e AuthConfiguration.new( status: :missing, diagnostic: Redactor.diagnostic(e) ) end |
#bin(env: ENV) ⇒ Object
72 73 74 75 76 77 |
# File 'lib/agent_cli_runtime/profile.rb', line 72 def bin(env: ENV) key = @env_bin_override_keys.find do |candidate| !env[candidate].to_s.empty? end key ? env.fetch(key) : @bin_default end |
#binary_installed?(env: ENV) ⇒ Boolean
135 136 137 138 139 140 141 142 143 144 145 |
# File 'lib/agent_cli_runtime/profile.rb', line 135 def binary_installed?(env: ENV) executable = bin(env:) return File.file?(executable) && File.executable?(executable) if executable.include?(File::SEPARATOR) env.fetch("PATH", "").split(File::PATH_SEPARATOR).any? do |directory| candidate = File.join(directory, executable) File.file?(candidate) && File.executable?(candidate) end rescue ArgumentError false end |
#check_version!(env: ENV) ⇒ Object
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 |
# File 'lib/agent_cli_runtime/profile.rb', line 147 def check_version!(env: ENV) executable = bin(env:) out, _err, status = bounded_capture3( executable, @version_flag, timeout_sec: CAPTURE_TIMEOUT_SECONDS, env: env ) unless status.success? raise BinaryUnavailable, "#{@name} binary not runnable: #{executable}" end versions = out.scan(VERSION_TOKEN_PATTERN).flatten.uniq if versions.empty? raise VersionError, "could not parse #{@name} #{@version_flag} output" end if versions.length > 1 raise VersionError, "ambiguous #{@name} #{@version_flag} output: " \ "#{versions.join(', ')}" end version = versions.fetch(0) if @min_version && Gem::Version.new(version) < Gem::Version.new(@min_version) raise VersionError, "#{@name} #{version} below minimum #{@min_version}" end version.freeze rescue Errno::ENOENT, Errno::EACCES => e raise BinaryUnavailable, "#{@name} binary not runnable: #{executable} (#{e.class.name.split('::').last})" rescue Timeout::Error raise BinaryUnavailable, "#{@name} version check timed out after #{CAPTURE_TIMEOUT_SECONDS}s: #{executable}" end |
#extract_usage_event(event) ⇒ Object
197 198 199 200 201 |
# File 'lib/agent_cli_runtime/profile.rb', line 197 def extract_usage_event(event) @usage_extractor.call(event) rescue StandardError nil end |
#identity_arguments(model:, effort:, pin_model: true) ⇒ Object
99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 |
# File 'lib/agent_cli_runtime/profile.rb', line 99 def identity_arguments(model:, effort:, pin_model: true) normalized_model = nonempty_value(model, "model") normalized_effort = effort.nil? ? nil : nonempty_value(effort, "effort") native_arguments = [] if pin_model unless @model_argument_builder raise UnsupportedCapability, "agent profile #{@name.inspect} cannot pin a model" end native_arguments.concat(@model_argument_builder.call(normalized_model)) end effective_effort = nil if normalized_effort unless @effort_argument_builder raise UnsupportedCapability, "agent profile #{@name.inspect} cannot set reasoning effort" end native_arguments.concat(@effort_argument_builder.call(normalized_effort)) effective_effort = normalized_effort end IdentityArguments.new( model: normalized_model, requested_effort: normalized_effort, effective_effort: effective_effort, effort_supported: !@effort_argument_builder.nil?, model_pinned: pin_model, native_arguments: validate_arguments(native_arguments) ) end |
#permission_flags(permission_mode = nil) ⇒ Object
79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 |
# File 'lib/agent_cli_runtime/profile.rb', line 79 def ( = nil) if == WORKSPACE_WRITE_PERMISSION_MODE return @workspace_write_flags.dup unless @workspace_write_flags.empty? raise ArgumentError, "agent profile #{@name.inspect} cannot enforce workspace-write sandboxing" end if == READ_ONLY_PERMISSION_MODE return @read_only_flags.dup unless @read_only_flags.empty? raise ArgumentError, "agent profile #{@name.inspect} cannot enforce read-only sandboxing" end return [] unless @permission_skip_flag return [ @permission_skip_flag ] unless @name == :claude && return [ @permission_skip_flag ] if == "bypassPermissions" [ "--permission-mode", .to_s ] end |
#raw_cli_arguments_supported? ⇒ Boolean
131 132 133 |
# File 'lib/agent_cli_runtime/profile.rb', line 131 def raw_cli_arguments_supported? @raw_cli_arguments_supported end |
#require_cli_capability!(capability) ⇒ Object
203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 |
# File 'lib/agent_cli_runtime/profile.rb', line 203 def require_cli_capability!(capability) capability_name = capability.to_sym flags = @cli_capabilities[capability_name] unless flags raise UnsupportedCapability, "agent profile #{@name.inspect} does not declare CLI capability " \ "#{capability_name.inspect}" end help = capture_help(flags) missing = flags.grep(/\A-/).reject { |flag| flag_advertised?(help, flag) } unless missing.empty? raise UnsupportedCapability, "#{@name} does not advertise required #{capability_name} capability " \ "(missing #{missing.join(', ')})" end flags.dup end |