Module: AgentCliRuntime::Runtime

Defined in:
lib/agent_cli_runtime/runtime.rb

Class Method Summary collapse

Class Method Details

.compile(request) ⇒ Object



5
6
7
8
9
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
61
62
63
64
# File 'lib/agent_cli_runtime/runtime.rb', line 5

def compile(request)
  unless request.is_a?(Request)
    raise ArgumentError,
          "request must be an AgentCliRuntime::Request"
  end

  profile = Profiles.resolve(request.profile)
  evidence = [ supported_evidence(profile, :headless) ]
  argv = [ request.executable || profile.bin ]
  prompt_style = profile.prompt_style
  argv << profile.headless_flag
  argv << request.prompt if prompt_style == :headless_flag_value

  argv.concat(
    permission_arguments(
      profile, request.permission_mode, evidence,
      trusted_arguments: request.permission_arguments
    )
  )
  argv.concat(directory_arguments(profile, request, evidence))
  argv.concat(tool_scope_arguments(profile, request, evidence))
  argv.concat(budget_arguments(profile, request.max_budget_usd, evidence))
  argv.concat(identity_arguments(profile, request, evidence))

  request.capabilities.each do |capability|
    capability_evidence = require_capability!(profile, capability)
    evidence << capability_evidence
    argv.concat(capability_evidence.arguments)
  end

  unless request.raw_cli_arguments.empty?
    unless profile.raw_cli_arguments_supported?
      unsupported!(
        profile, :raw_cli_arguments,
        "agent profile #{profile.name.inspect} does not accept raw CLI arguments"
      )
    end
    evidence << supported_evidence(
      profile, :raw_cli_arguments, request.raw_cli_arguments
    )
    argv.concat(request.raw_cli_arguments)
  end
  argv.concat(request.trusted_cli_arguments)
  argv.concat(profile.output_format_flags) if request.include_output_format
  argv << (prompt_style == :stdin ? "-" : request.prompt) unless
    prompt_style == :headless_flag_value

  CompiledInvocation.new(
    argv: request.command_prefix + argv,
    stdin_data: prompt_style == :stdin ? request.prompt : nil,
    provider: profile.name,
    launcher_identity: profile.launcher_identity,
    capability_evidence: evidence
  )
rescue Error
  raise
rescue StandardError => e
  profile = Profiles.resolve(request.profile) if request.is_a?(Request)
  compilation_error!(profile, e)
end

.extract_usage(profile, event) ⇒ Object



97
98
99
100
101
102
103
104
# File 'lib/agent_cli_runtime/runtime.rb', line 97

def extract_usage(profile, event)
  resolved = Profiles.resolve(profile)
  begin
    normalize_usage(resolved.extract_usage_event(event))
  rescue StandardError
    nil
  end
end

.observe(profile, result) ⇒ Object



106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
# File 'lib/agent_cli_runtime/runtime.rb', line 106

def observe(profile, result)
  resolved = Profiles.resolve(profile)
  raw = result.is_a?(Hash) ? result : {}
  ObservableResult.new(
    provider: resolved.name,
    launcher_identity: resolved.launcher_identity,
    exit_code: raw[:exit_code],
    timed_out: raw[:timed_out],
    status: raw[:status],
    usage: normalize_usage(raw[:usage]),
    final_message: raw[:final_message],
    diagnostic: Redactor.diagnostic(
      raw[:error_message] || raw[:limit_text]
    )
  )
end

.prepare!(profile) ⇒ Object

Raises:



66
67
68
69
70
71
72
73
74
75
76
77
78
# File 'lib/agent_cli_runtime/runtime.rb', line 66

def prepare!(profile)
  resolved = Profiles.resolve(profile)
  result = Probe.call(resolved)
  return result if result.ready

  evidence = unsupported_evidence(
    resolved, :probe, result.diagnostic || "local prerequisites unavailable"
  )
  raise ProbeError.new(
    "agent profile #{resolved.name.inspect} probe failed: #{evidence.diagnostic}",
    evidence: evidence
  )
end

.require_capability!(profile, capability) ⇒ Object



80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
# File 'lib/agent_cli_runtime/runtime.rb', line 80

def require_capability!(profile, capability)
  resolved = Profiles.resolve(profile)
  arguments = resolved.require_cli_capability!(capability)
  supported_evidence(resolved, capability, arguments)
rescue UnknownProvider
  raise
rescue Error => e
  evidence = unsupported_evidence(
    resolved, capability, Redactor.diagnostic(e)
  )
  raise UnsupportedCapability.new(
    "agent profile #{resolved.name.inspect} cannot provide " \
    "#{capability.to_sym.inspect}: #{evidence.diagnostic}",
    evidence: evidence
  ), cause: e
end

.supported_evidence(profile, capability, arguments = []) ⇒ Object



123
124
125
126
127
128
129
130
131
# File 'lib/agent_cli_runtime/runtime.rb', line 123

def supported_evidence(profile, capability, arguments = [])
  CapabilityEvidence.new(
    capability: capability,
    supported: true,
    provider: profile.name,
    launcher_identity: profile.launcher_identity,
    arguments: arguments
  )
end

.unsupported_evidence(profile, capability, diagnostic) ⇒ Object



133
134
135
136
137
138
139
140
141
# File 'lib/agent_cli_runtime/runtime.rb', line 133

def unsupported_evidence(profile, capability, diagnostic)
  CapabilityEvidence.new(
    capability: capability,
    supported: false,
    provider: profile&.name || :unknown,
    launcher_identity: profile&.launcher_identity || "unknown",
    diagnostic: Redactor.diagnostic(diagnostic)
  )
end